static enum pbpal_resolv_n_connect_result resolv_and_connect_wout_SSL(pubnub_t *pb) { PUBNUB_LOG_TRACE("resolv_and_connect_wout_SSL\n"); if (NULL == pb->pal.socket) { char const*origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN; PUBNUB_LOG_TRACE("pb=%p: Don't have BIO\n", pb); pb->pal.socket = BIO_new_connect((char*)origin); } if (NULL == pb->pal.socket) { return pbpal_resolv_resource_failure; } BIO_set_conn_port(pb->pal.socket, "http"); BIO_set_nbio(pb->pal.socket, !pb->options.use_blocking_io); WATCH_ENUM(pb->options.use_blocking_io); if (BIO_do_connect(pb->pal.socket) <= 0) { if (BIO_should_retry(pb->pal.socket)) { return pbpal_connect_wouldblock; } ERR_print_errors_cb(print_to_pubnub_log, NULL); PUBNUB_LOG_ERROR("BIO_do_connect failed\n"); return pbpal_connect_failed; } PUBNUB_LOG_TRACE("pb=%p: BIO connected\n", pb); { int fd = BIO_get_fd(pb->pal.socket, NULL); socket_set_rcv_timeout(fd, pb->transaction_timeout_ms); } return pbpal_connect_success; }
static int openssl_bio_new_connect(lua_State *L) { const char *host = luaL_checkstring(L, 1); BIO* bio = BIO_new_connect((char*)host); int doconn = 1; if (lua_isstring(L, 2)) { if (BIO_set_conn_port(bio, lua_tostring(L, 2)) <= 0) { BIO_free(bio); bio = NULL; } else { doconn = lua_isnoneornil(L, 3) ? doconn : auxiliar_checkboolean(L, 3); } } else doconn = auxiliar_checkboolean(L, 2); if (bio) { int ret = 1; if (doconn) { ret = BIO_do_connect(bio); } if (ret == 1) { PUSH_OBJECT(bio, "openssl.bio"); openssl_newvalue(L, bio); lua_pushboolean(L, 1); openssl_setvalue(L, bio, "free_all"); return 1; } else { BIO_free(bio); luaL_error(L, "Error creating connection to remote machine"); } } if (!bio) luaL_error(L, "Error creating connection BIO"); return 0; }
// ---------------------------------------------------------------------------- void SecureClient::init() { SSL_load_error_strings(); ERR_load_BIO_strings(); OpenSSL_add_all_algorithms(); m_ssl_context = SSL_CTX_new(SSLv23_client_method()); // loading the Trust Store if(!SSL_CTX_load_verify_locations(m_ssl_context, "../client/certs/TrustStore.pem", nullptr)) { ERR("Failed to load the Trust Store of certificates: %s", ERR_reason_error_string(ERR_get_error())); throw ClientException(); } m_bio = BIO_new_ssl_connect(m_ssl_context); if (m_bio == nullptr) { ERR("Failed to prepare new secure connection: %s", ERR_reason_error_string(ERR_get_error())); throw ClientException(); } BIO_get_ssl(m_bio, &m_ssl); SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY); // retry handshake transparently if Server suddenly wants // establish secure connection BIO_set_conn_hostname(m_bio, m_ip_address.c_str()); BIO_set_conn_port(m_bio, m_port.c_str()); if (BIO_do_connect(m_bio) <= 0) { ERR("Failed to securely connect to [%s:%s]: %s", m_ip_address.c_str(), m_port.c_str(), ERR_reason_error_string(ERR_get_error())); m_is_connected = false; } else { m_is_connected = true; } // checking certificate from Server if (SSL_get_verify_result(m_ssl) != X509_V_OK) { WRN("Certificate verification has failed: %s", ERR_reason_error_string(ERR_get_error())); // TODO: probably, proceed further } INF("Secure connection has been established"); m_api_impl = new SecureClientApiImpl(m_bio, m_ip_address, m_port); }
/* Connect to host on the given port using tls and return the BIO object representing the connection. */ BIO* connect_tls(const char *host, const char *port){ init_ssl_lib(); //the assignment is redundant, but it's weird not having it ctx = init_ssl_ctx(); if(!ctx){return NULL;} BIO *bio = BIO_new_ssl_connect(ctx); if(!bio){goto err;} if(BIO_set_conn_hostname(bio, host) == 0){ goto err; } if(BIO_set_conn_port(bio, port) == 0){ goto err; } SSL *ssl; BIO_get_ssl(bio, &ssl); //Handle renegotiation transparently SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); //this is to let the server know what name we used to connect to it SSL_set_tlsext_host_name(ssl, host); if(BIO_do_connect(bio) == 0){ goto err; } if(BIO_do_handshake(bio) == 0){ goto err; } //make sure that the certificate was valid if(SSL_get_verify_result(ssl) != X509_V_OK){ goto err; } return bio; err: print_errors(); BIO_free_all(bio); SSL_CTX_free(ctx); return NULL; }
int BIO_set_conn_int_port(BIO *bio, const int *port) { char buf[DECIMAL_SIZE(int) + 1]; BIO_snprintf(buf, sizeof(buf), "%d", *port); return BIO_set_conn_port(bio, buf); }
void secure_and_send(int client_fd, char* read_pipe, char* write_pipe, int index, FILE* d_out){ BIO* bio; SSL* ssl; SSL_CTX* ctx; /*init ssl library*/ SSL_library_init(); ERR_load_BIO_strings(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); /* Set up the SSL context */ ctx = SSL_CTX_new(SSLv23_client_method()); /* Load the trust store */ if(! SSL_CTX_load_verify_locations(ctx, "cacerts.pem", NULL)) { fprintf(stderr, "Error loading trust store\n"); ERR_print_errors_fp(stderr); SSL_CTX_free(ctx); return; } /* Setup the connection */ bio = BIO_new_ssl_connect(ctx); /* Set the SSL_MODE_AUTO_RETRY flag */ BIO_get_ssl(bio, & ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* Create and setup the connection */ char host[LINE]; sprintf(host,"%s:%s",safe_host[index],safe_port[index]); BIO_set_conn_hostname(bio, safe_host[index]); BIO_set_conn_port(bio,safe_port[index]); if(BIO_do_connect(bio) <= 0) { fprintf(stderr, "Error attempting to connect\n"); ERR_print_errors_fp(stderr); BIO_free_all(bio); SSL_CTX_free(ctx); return; } /* Check the certificate */ if(SSL_get_verify_result(ssl) != X509_V_OK) { fprintf(stderr, "Certificate verification error: %lu\n", SSL_get_verify_result(ssl)); BIO_free_all(bio); SSL_CTX_free(ctx); return; } /* Send the request */ BIO_write(bio, read_pipe, strlen(read_pipe)); /* Read in the response */ for(;;) { int p = BIO_read(bio, write_pipe, PIPE_MAX); if(p <= 0) break; p = write(client_fd,write_pipe,p); } /* Close the connection and free the context */ BIO_free_all(bio); SSL_CTX_free(ctx); close(client_fd); fclose(d_out); return; }
QByteArray SSLConnect::getUrl( RequestType type, const QString &value ) { if( !d->ssl ) return QByteArray(); if( !SSL_check_private_key( d->ssl ) ) { d->setError(); return QByteArray(); } QString label; HTTPRequest req; switch( type ) { case AccessCert: { label = tr("Loading server access certificate. Please wait."); SOAPDocument s( "GetAccessToken", "urn:GetAccessToken" ); s.writeParameter( "Language", Settings::language().toUpper() ); s.writeParameter( "RequestTime", "" ); s.writeParameter( "SoftwareName", "DigiDoc3" ); s.writeParameter( "SoftwareVersion", qApp->applicationVersion() ); s.finalize(); req = HTTPRequest( "POST", "1.1", "https://id.sk.ee/GetAccessTokenWS/" ); req.setRawHeader( "Content-Type", "text/xml" ); req.setRawHeader( "SOAPAction", QByteArray() ); req.setRawHeader( "Connection", "close" ); req.setContent( s.document() ); break; } case MobileInfo: { label = tr("Loading Mobile info"); SOAPDocument s( "GetMIDTokens", "urn:GetMIDTokens" ); s.finalize(); req = HTTPRequest( "POST", "1.1", "https://id.sk.ee/MIDInfoWS/" ); req.setRawHeader( "Content-Type", "text/xml" ); req.setRawHeader( "SOAPAction", QByteArray() ); req.setRawHeader( "Connection", "close" ); req.setContent( s.document() ); break; } case EmailInfo: label = tr("Loading Email info"); req = HTTPRequest( "GET", "1.0", "https://sisene.www.eesti.ee/idportaal/postisysteem.naita_suunamised" ); break; case ActivateEmails: label = tr("Loading Email info"); req = HTTPRequest( "GET", "1.0", QString("https://www.eesti.ee/portaal/!postisysteem.suunamised?%1").arg( value ) ); break; case PictureInfo: label = tr("Downloading picture"); req = HTTPRequest( "GET", "1.0", "https://sisene.www.eesti.ee/idportaal/portaal.idpilt" ); break; default: return QByteArray(); } QByteArray url = req.url().host().toUtf8(); BIO *sock = BIO_new_connect( (char*)url.constData() ); BIO_set_conn_port( sock, "https" ); if( BIO_do_connect( sock ) <= 0 ) { d->setError( tr( "Failed to connect to host. Are you connected to the internet?" ) ); return QByteArray(); } SSL_set_bio( d->ssl, sock, sock ); if( !SSL_connect( d->ssl ) ) { d->setError(); return QByteArray(); } QByteArray header = req.request(); if( !SSL_write( d->ssl, header.constData(), header.size() ) ) { d->setError(); return QByteArray(); } QProgressDialog p( label, QString(), 0, 0, qApp->activeWindow() ); p.setWindowFlags( (p.windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowCloseButtonHint ); if( QProgressBar *bar = p.findChild<QProgressBar*>() ) bar->setTextVisible( false ); p.open(); return SSLReadThread( d ).waitForDone(); }
/* * This function sends a OCSP request to a defined OCSP responder * and checks the OCSP response for correctness. */ static int ocsp_check(X509_STORE *store, X509 *issuer_cert, X509 *client_cert, EAP_TLS_CONF *conf) { OCSP_CERTID *certid; OCSP_REQUEST *req; OCSP_RESPONSE *resp; OCSP_BASICRESP *bresp = NULL; char *host = NULL; char *port = NULL; char *path = NULL; int use_ssl = -1; BIO *cbio; int ocsp_ok; int status; /* * Create OCSP Request */ certid = OCSP_cert_to_id(NULL, client_cert, issuer_cert); req = OCSP_REQUEST_new(); OCSP_request_add0_id(req, certid); OCSP_request_add1_nonce(req, NULL, 8); /* * Send OCSP Request and get OCSP Response */ /* Get OCSP responder URL */ if(conf->ocsp_override_url) { OCSP_parse_url(conf->ocsp_url, &host, &port, &path, &use_ssl); } else { ocsp_parse_cert_url(client_cert, &host, &port, &path, &use_ssl); } DEBUG2("[ocsp] --> Responder URL = http://%s:%s%s", host, port, path); /* Setup BIO socket to OCSP responder */ cbio = BIO_new_connect(host); BIO_set_conn_port(cbio, port); BIO_do_connect(cbio); /* Send OCSP request and wait for response */ resp = OCSP_sendreq_bio(cbio, path, req); if(resp==0) { radlog(L_ERR, "Error: Couldn't get OCSP response"); ocsp_ok = 0; goto ocsp_end; } /* Verify OCSP response */ status = OCSP_response_status(resp); if(status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { radlog(L_ERR, "Error: OCSP response status: %s", OCSP_response_status_str(status)); ocsp_ok = 0; goto ocsp_end; } bresp = OCSP_response_get1_basic(resp); if(OCSP_check_nonce(req, bresp)!=1) { radlog(L_ERR, "Error: OCSP response has wrong nonce value"); ocsp_ok = 0; goto ocsp_end; } if(OCSP_basic_verify(bresp, NULL, store, 0)!=1){ radlog(L_ERR, "Error: Couldn't verify OCSP basic response"); ocsp_ok = 0; goto ocsp_end; } ocsp_ok = 1; ocsp_end: /* Free OCSP Stuff */ OCSP_REQUEST_free(req); OCSP_RESPONSE_free(resp); free(host); free(port); free(path); BIO_free_all(cbio); OCSP_BASICRESP_free(bresp); if (ocsp_ok) { DEBUG2("[ocsp] --> Certificate is valid!"); } else { DEBUG2("[ocsp] --> Certificate has been expired/revoked!"); } return ocsp_ok; }
/** * Run SSL handshake and store the resulting time value in the * 'time_map'. * * @param time_map where to store the current time * @param time_is_an_illusion * @param http whether to do an http request and take the date from that * instead. */ static void run_ssl (uint32_t *time_map, int time_is_an_illusion, int http) { BIO *s_bio; SSL_CTX *ctx; SSL *ssl; struct stat statbuf; uint32_t result_time; SSL_load_error_strings(); SSL_library_init(); ctx = NULL; if (0 == strcmp("sslv23", protocol)) { verb ("V: using SSLv23_client_method()"); ctx = SSL_CTX_new(SSLv23_client_method()); } else if (0 == strcmp("sslv3", protocol)) { verb ("V: using SSLv3_client_method()"); ctx = SSL_CTX_new(SSLv3_client_method()); } else if (0 == strcmp("tlsv1", protocol)) { verb ("V: using TLSv1_client_method()"); ctx = SSL_CTX_new(TLSv1_client_method()); } else die("Unsupported protocol `%s'", protocol); if (ctx == NULL) die("OpenSSL failed to support protocol `%s'", protocol); verb("V: Using OpenSSL for SSL"); if (ca_racket) { if (-1 == stat(ca_cert_container, &statbuf)) { die("Unable to stat CA certficate container %s", ca_cert_container); } else { switch (statbuf.st_mode & S_IFMT) { case S_IFREG: if (1 != SSL_CTX_load_verify_locations(ctx, ca_cert_container, NULL)) fprintf(stderr, "SSL_CTX_load_verify_locations failed"); break; case S_IFDIR: if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) fprintf(stderr, "SSL_CTX_load_verify_locations failed"); break; default: if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) { fprintf(stderr, "SSL_CTX_load_verify_locations failed"); die("Unable to load CA certficate container %s", ca_cert_container); } } } } if (NULL == (s_bio = make_ssl_bio(ctx))) die ("SSL BIO setup failed"); BIO_get_ssl(s_bio, &ssl); if (NULL == ssl) die ("SSL setup failed"); if (time_is_an_illusion) { SSL_set_info_callback(ssl, openssl_time_callback); } SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); verb("V: opening socket to %s:%s", host, port); if ( (1 != BIO_set_conn_hostname(s_bio, host)) || (1 != BIO_set_conn_port(s_bio, port)) ) die ("Failed to initialize connection to `%s:%s'", host, port); if (NULL == BIO_new_fp(stdout, BIO_NOCLOSE)) die ("BIO_new_fp returned error, possibly: %s", strerror(errno)); // This should run in seccomp // eg: prctl(PR_SET_SECCOMP, 1); if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later? die ("SSL connection failed"); if (1 != BIO_do_handshake(s_bio)) die ("SSL handshake failed"); // from /usr/include/openssl/ssl3.h // ssl->s3->server_random is an unsigned char of 32 bits memcpy(&result_time, ssl->s3->server_random, sizeof (uint32_t)); verb("V: In TLS response, T=%lu", (unsigned long)ntohl(result_time)); if (http) { char buf[1024]; verb_debug ("V: Starting HTTP"); if (snprintf(buf, sizeof(buf), HTTP_REQUEST, HTTPS_USER_AGENT, hostname_to_verify) >= 1024) die("hostname too long"); buf[1023]='\0'; /* Unneeded. */ verb_debug ("V: Writing HTTP request"); if (1 != write_all_to_bio(s_bio, buf)) die ("write all to bio failed."); verb_debug ("V: Reading HTTP response"); if (1 != read_http_date_from_bio(s_bio, &result_time)) die ("read all from bio failed."); verb ("V: Received HTTP response. T=%lu", (unsigned long)result_time); result_time = htonl(result_time); } // Verify the peer certificate against the CA certs on the local system if (ca_racket) { inspect_key (ssl, hostname_to_verify); } else { verb ("V: Certificate verification skipped!"); } check_key_length(ssl); memcpy(time_map, &result_time, sizeof (uint32_t)); SSL_free(ssl); SSL_CTX_free(ctx); }
/** * Run SSL handshake and store the resulting time value in the * 'time_map'. * * @param time_map where to store the current time */ static void run_ssl (uint32_t *time_map, int time_is_an_illusion) { BIO *s_bio; SSL_CTX *ctx; SSL *ssl; SSL_load_error_strings(); SSL_library_init(); ctx = NULL; if (0 == strcmp("sslv23", protocol)) { verb ("V: using SSLv23_client_method()\n"); ctx = SSL_CTX_new(SSLv23_client_method()); } else if (0 == strcmp("sslv3", protocol)) { verb ("V: using SSLv3_client_method()\n"); ctx = SSL_CTX_new(SSLv3_client_method()); } else if (0 == strcmp("tlsv1", protocol)) { verb ("V: using TLSv1_client_method()\n"); ctx = SSL_CTX_new(TLSv1_client_method()); } else die("Unsupported protocol `%s'\n", protocol); if (ctx == NULL) die("OpenSSL failed to support protocol `%s'\n", protocol); if (ca_racket) { if (1 != SSL_CTX_load_verify_locations(ctx, NULL, certdir)) fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); } if (NULL == (s_bio = BIO_new_ssl_connect(ctx))) die ("SSL BIO setup failed\n"); BIO_get_ssl(s_bio, &ssl); if (NULL == ssl) die ("SSL setup failed\n"); if (time_is_an_illusion) { SSL_set_info_callback(ssl, openssl_time_callback); } SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); if ( (1 != BIO_set_conn_hostname(s_bio, host)) || (1 != BIO_set_conn_port(s_bio, port)) ) die ("Failed to initialize connection to `%s:%s'\n", host, port); if (NULL == BIO_new_fp(stdout, BIO_NOCLOSE)) die ("BIO_new_fp returned error, possibly: %s", strerror(errno)); // This should run in seccomp // eg: prctl(PR_SET_SECCOMP, 1); if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later? die ("SSL connection failed\n"); if (1 != BIO_do_handshake(s_bio)) die ("SSL handshake failed\n"); // Verify the peer certificate against the CA certs on the local system if (ca_racket) { inspect_key (ssl, host); } else { verb ("V: Certificate verification skipped!\n"); } check_key_length(ssl); // from /usr/include/openssl/ssl3.h // ssl->s3->server_random is an unsigned char of 32 bits memcpy(time_map, ssl->s3->server_random, sizeof (uint32_t)); SSL_free(ssl); SSL_CTX_free(ctx); }
BIO * httpsGetFileDesc(char * hostname, int port, char * remotename, char *extraHeaders, int *errorcode, char **returnedHeaders) { char *buf; char headers[4096]; char *nextChar = headers; char *hstr; int sock; int rc; int checkedCode; int headerslen; int bufsize; int byteswritten; struct loaderData_s * loaderData; SSL_CTX *ssl_context; SSL *ssl; BIO *sbio = 0; X509 *server_cert; *errorcode = 0; sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sock < 0) { logMessage(ERROR, "ROCKS:httpsGetFileDesc:Could not get a socket"); *errorcode = FTPERR_FAILED_CONNECT; return NULL; } /* OpenSSL_add_all_algorithms(); */ SSLeay_add_ssl_algorithms(); ssl_context = SSL_CTX_new(SSLv23_client_method()); if (!ssl_context) { logMessage(ERROR, "Could not create SSLv2,3 context"); *errorcode = FTPERR_FAILED_CONNECT; goto error; } /* Pull in the Global Loader Data structure. */ loaderData = rocks_global_loaderData; /* I have a Certificate */ if (loaderData->cert_filename) { rc = SSL_CTX_use_certificate_file(ssl_context, loaderData->cert_filename, SSL_FILETYPE_PEM); if (!rc) { logMessage(ERROR, "Could not read Cluster Certificate"); *errorcode = FTPERR_CLIENT_SECURITY; goto error; } rc = SSL_CTX_use_PrivateKey_file(ssl_context, loaderData->priv_filename, SSL_FILETYPE_PEM); if (!rc) { logMessage(ERROR, "Could not read Cluster cert private key"); *errorcode = FTPERR_CLIENT_SECURITY; goto error; } /* Only connect to servers that have certs signed by * our trusted CA. */ if (loaderData->authParent) { rc = SSL_CTX_load_verify_locations(ssl_context, loaderData->ca_filename, 0); if (!rc) { logMessage(ERROR, "Could not read Server CA cert"); *errorcode = FTPERR_CLIENT_SECURITY; goto error; } SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, 0); SSL_CTX_set_verify_depth(ssl_context, 1); } } sbio = BIO_new_ssl_connect(ssl_context); if (!sbio) { logMessage(ERROR, "Could not create SSL object"); *errorcode = FTPERR_CLIENT_SECURITY; goto error; } BIO_get_ssl(sbio, &ssl); if (!ssl) { logMessage(ERROR, "Could not find ssl pointer."); *errorcode = FTPERR_CLIENT_SECURITY; goto error; } SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); BIO_set_conn_hostname(sbio, hostname); BIO_set_conn_port(sbio, "https"); rc = BIO_do_connect(sbio); if (rc<=0) { rc = SSL_get_verify_result(ssl); if (rc) { logMessage(ERROR, "Could not verify %s's identity", hostname); *errorcode = FTPERR_REFUSED; goto error; } logMessage(ERROR, "Could not connect to %s:https", hostname); *errorcode = FTPERR_FAILED_CONNECT; goto error; } rc = BIO_do_handshake(sbio); if (rc<=0) { logMessage(ERROR, "Could not establish HTTPS connection with %s", hostname); *errorcode = FTPERR_FAILED_CONNECT; goto error; } server_cert = SSL_get_peer_certificate(ssl); /* Show credentials if appropriate. */ /* Don't Show Credentials */ if ( (0 == 1) && !loaderData->cert_filename && !loaderData->ekv && !loaderData->dropCert) { rc = show_cert(server_cert); if (rc != 1) { *errorcode = FTPERR_REFUSED; goto error; } } if (extraHeaders) hstr = extraHeaders; else hstr = ""; bufsize = strlen(remotename) + strlen(hostname) + strlen(hstr) + 30; if ((buf = malloc(bufsize)) == NULL) { logMessage(ERROR, "ROCKS:httpsGetFileDesc:malloc failed"); *errorcode = FTPERR_FAILED_CONNECT; goto error; } sprintf(buf, "GET %s HTTP/1.0\r\nHost: %s\r\n%s\r\n", remotename, hostname, hstr); byteswritten = BIO_puts(sbio, buf); logMessage(INFO, "ROCKS:httpsGetFileDesc:byteswritten(%d)", byteswritten); logMessage(INFO, "ROCKS:httpsGetFileDesc:bufsize(%d)", (int)strlen(buf)); free(buf); /* This is fun; read the response a character at a time until we: 1) Get our first \r\n; which lets us check the return code 2) Get a \r\n\r\n, which means we're done */ *nextChar = '\0'; checkedCode = 0; headerslen = 0; while (!strstr(headers, "\r\n\r\n")) { if (BIO_read(sbio, nextChar, 1) != 1) { *errorcode = FTPERR_SERVER_SECURITY; goto error; } nextChar++; *nextChar = '\0'; ++headerslen; if (nextChar - headers == sizeof(headers)) { goto error; } if (!checkedCode && strstr(headers, "\r\n")) { char * start, * end; checkedCode = 1; start = headers; while (!isspace(*start) && *start) start++; if (!*start) { goto error; } while (isspace(*start) && *start) start++; end = start; while (!isspace(*end) && *end) end++; if (!*end) { goto error; } logMessage(INFO, "ROCKS:httpsGetFileDesc:status %s.", start); *end = '\0'; if (!strcmp(start, "404")) goto error; else if (!strcmp(start, "403")) { *errorcode = FTPERR_SERVER_SECURITY; goto error; } else if (!strcmp(start, "503")) { /* A server nack - busy */ logMessage(WARNING, "ROCKS:server busy"); watchdog_reset(); *errorcode = FTPERR_FAILED_DATA_CONNECT; goto error; } else if (strcmp(start, "200")) { *errorcode = FTPERR_BAD_SERVER_RESPONSE; goto error; } *end = ' '; } } if ((*returnedHeaders = (char *)malloc(headerslen + 1)) != NULL) { memcpy(*returnedHeaders, headers, headerslen + 1); } return sbio; error: close(sock); if (sbio) BIO_free_all(sbio); if (!*errorcode) *errorcode = FTPERR_SERVER_IO_ERROR; logMessage(ERROR, "ROCKS:httpsGetFileDesc:Error %s", ftpStrerror(*errorcode, URL_METHOD_HTTP)); return NULL; }
int main(int argc, char **argv) { BIO *bio; SSL *ssl; SSL_ERR err; char c; char *host = "google.com"; char *port = "443"; char *sendtemplate = "HEAD / HTTP/1.1\r\nHost: %s\r\n\r\n"; char sendbuf[BUFFSZ]; char recvbuf[BUFFSZ]; int nbytes; SSL_library_init(); SSL_load_error_strings(); ERR_load_BIO_strings(); OpenSSL_add_all_algorithms(); SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); while((c = getopt(argc, argv, "h:p:")) != -1) { switch(c) { case 'h': host = optarg; break; case 'p': port = optarg; break; case '?': return 1; break; } } snprintf(sendbuf, BUFFSZ, sendtemplate, host); if(!ctx) { err = ERR_get_error(); printf("%s\n", ERR_error_string(err, NULL)); return 1; } bio = BIO_new_ssl_connect(ctx); BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); BIO_set_conn_hostname(bio, host); BIO_set_conn_port(bio, port); if(BIO_do_connect(bio) <= 0) { err = ERR_get_error(); printf("%s\n", ERR_error_string(err, NULL)); return 1; } /* * TODO flesh this out * send request, and print the response */ BIO_write(bio, sendbuf, strlen(sendbuf)); nbytes = BIO_read(bio, recvbuf, sizeof(recvbuf)); printf("%s\n", recvbuf); BIO_free_all(bio); return 0; }
int SSLBufferConnect(struct sslbuffer_t *sslbuffer, const char *host, const char *port) { int res; int fd; struct event *ev_write = NULL; struct event *ev_read = NULL; BIO *bio = NULL; unsigned long error; bio = BIO_new(BIO_s_connect( )); if (bio == NULL) return 0; BIO_set_conn_hostname(bio, host); BIO_set_conn_port(bio, port); BIO_set_nbio(bio, 1); SSL_set_bio(sslbuffer->ssl, bio, bio); res = SSL_connect(sslbuffer->ssl); if (res <= 0) { error = SSL_get_error(sslbuffer->ssl, res); sslbuffer->fl_connecting = 1; if ( (error != SSL_ERROR_WANT_CONNECT) && (error != SSL_ERROR_WANT_READ) && (error != SSL_ERROR_WANT_WRITE) ) { printf("%s:%d: unknown error %lu\n", __FILE__, __LINE__, error); print_errors(); goto Error; } } fd = BIO_get_fd(bio, NULL); ev_read = event_new(sslbuffer->base, fd, EV_READ|EV_PERSIST, SSLBuffer_func, sslbuffer); if (ev_read == NULL) goto Error; res = event_add(ev_read, NULL); if (res != 0) goto Error; sslbuffer->ev_read = ev_read; ev_write = event_new(sslbuffer->base, fd, EV_WRITE|EV_PERSIST, SSLBuffer_func, sslbuffer); if (ev_write == NULL) goto Error; res = event_add(ev_write, NULL); if (res != 0) goto Error; sslbuffer->ev_write = ev_write; return 1; Error: if (ev_write != NULL) event_free(ev_write); if (ev_read != NULL) event_free(ev_read); return 0; }
int proxy_null(BIO **cbio, BIO **sbio, char *header) { char data[READ_BUFF_SIZE]; int len, written; char *host, *p; /* retrieve the host tag */ host = strcasestr(header, HTTP_HOST_TAG); if (host == NULL) return -EINVALID; SAFE_STRDUP(host, host + strlen(HTTP_HOST_TAG)); /* trim the eol */ if ((p = strchr(host, '\r')) != NULL) *p = 0; if ((p = strchr(host, '\n')) != NULL) *p = 0; /* connect to the real server */ *sbio = BIO_new(BIO_s_connect()); BIO_set_conn_hostname(*sbio, host); BIO_set_conn_port(*sbio, "http"); if (BIO_do_connect(*sbio) <= 0) { DEBUG_MSG(D_ERROR, "Cannot connect to [%s]", host); SAFE_FREE(host); return -ENOADDRESS; } DEBUG_MSG(D_INFO, "Connection to [%s]", host); /* * sanitize the header to avoid strange reply from the server. * we don't want to cope with keep-alive !!! */ sanitize_header(header); /* send the request to the server */ BIO_puts(*sbio, header); memset(data, 0, sizeof(data)); written = 0; /* read the reply header from the server */ LOOP { len = BIO_read(*sbio, data + written, sizeof(char)); if (len <= 0) break; written += len; if (strstr(data, CR LF CR LF) || strstr(data, LF LF)) break; } /* send the headers to the client, the data will be sent in the callee function */ BIO_write(*cbio, data, written); SAFE_FREE(host); return ESUCCESS; }
//-------------------------------------------------- // sends an OCSP_REQUES object to remore server and // retrieves the OCSP_RESPONSE object // resp - buffer to store the new responses pointer // req - request objects pointer // url - OCSP responder URL //-------------------------------------------------- int ddocPullUrl(const char* url, DigiDocMemBuf* pSendData, DigiDocMemBuf* pRecvData, const char* proxyHost, const char* proxyPort) { BIO* cbio = 0, *sbio = 0; SSL_CTX *ctx = NULL; char *host = NULL, *port = NULL, *path = "/", buf[200]; int err = ERR_OK, use_ssl = -1, rc; long e; //RETURN_IF_NULL_PARAM(pSendData); // may be null if nothing to send? RETURN_IF_NULL_PARAM(pRecvData); RETURN_IF_NULL_PARAM(url); ddocDebug(4, "ddocPullUrl", "URL: %s, in: %d bytes", url, pSendData->nLen); //there is an HTTP proxy - connect to that instead of the target host if (proxyHost != 0 && *proxyHost != '\0') { host = (char*)proxyHost; if(proxyPort != 0 && *proxyPort != '\0') port = (char*)proxyPort; path = (char*)url; } else { if(OCSP_parse_url((char*)url, &host, &port, &path, &use_ssl) == 0) { ddocDebug(1, "ddocPullUrl", "Failed to parse the URL"); return ERR_WRONG_URL_OR_PROXY; } } if((cbio = BIO_new_connect(host)) != 0) { ddocDebug(4, "ddocPullUrl", "Host: %s port: %s", host, port); if(port != NULL) { BIO_set_conn_port(cbio, port); } if(use_ssl == 1) { ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); sbio = BIO_new_ssl(ctx, 1); cbio = BIO_push(sbio, cbio); } if ((rc = BIO_do_connect(cbio)) > 0) { ddocDebug(4, "ddocPullUrl", "Connected: %d", rc); if(pSendData && pSendData->nLen && pSendData->pMem) { rc = BIO_write(cbio, pSendData->pMem, pSendData->nLen); ddocDebug(4, "ddocPullUrl", "Sent: %d bytes, got: %d", pSendData->nLen, rc); } do { memset(buf, 0, sizeof(buf)); rc = BIO_read(cbio, buf, sizeof(buf)-1); ddocDebug(4, "ddocPullUrl", "Received: %d bytes\n", rc); if(rc > 0) err = ddocMemAppendData(pRecvData, buf, rc); } while(rc > 0); ddocDebug(4, "ddocPullUrl", "Total received: %d bytes\n", pRecvData->nLen); } else { //if no connection e = checkErrors(); if(ERR_GET_REASON(e) == BIO_R_BAD_HOSTNAME_LOOKUP || ERR_GET_REASON(e) == OCSP_R_SERVER_WRITE_ERROR) err = ERR_CONNECTION_FAILURE; else err = (host != NULL) ? ERR_WRONG_URL_OR_PROXY : ERR_CONNECTION_FAILURE; } BIO_free_all(cbio); if (use_ssl != -1) { OPENSSL_free(host); OPENSSL_free(port); OPENSSL_free(path); SSL_CTX_free(ctx); } } else err = ERR_CONNECTION_FAILURE; return(err); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char **args; char *host = NULL, *port = NULL, *path = "/"; char *reqin = NULL, *respin = NULL; char *reqout = NULL, *respout = NULL; char *signfile = NULL, *keyfile = NULL; char *rsignfile = NULL, *rkeyfile = NULL; char *outfile = NULL; int add_nonce = 1, noverify = 0, use_ssl = -1; OCSP_REQUEST *req = NULL; OCSP_RESPONSE *resp = NULL; OCSP_BASICRESP *bs = NULL; X509 *issuer = NULL, *cert = NULL; X509 *signer = NULL, *rsigner = NULL; EVP_PKEY *key = NULL, *rkey = NULL; BIO *acbio = NULL, *cbio = NULL; BIO *derbio = NULL; BIO *out = NULL; int req_text = 0, resp_text = 0; long nsec = MAX_VALIDITY_PERIOD, maxage = -1; char *CAfile = NULL, *CApath = NULL; X509_STORE *store = NULL; SSL_CTX *ctx = NULL; STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; int ret = 1; int accept_count = -1; int badarg = 0; int i; int ignore_err = 0; STACK *reqnames = NULL; STACK_OF(OCSP_CERTID) *ids = NULL; X509 *rca_cert = NULL; char *ridx_filename = NULL; char *rca_filename = NULL; CA_DB *rdb = NULL; int nmin = 0, ndays = -1; if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); args = argv + 1; reqnames = sk_new_null(); ids = sk_OCSP_CERTID_new_null(); while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-url")) { if (args[1]) { args++; if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) { BIO_printf(bio_err, "Error parsing URL\n"); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-host")) { if (args[1]) { args++; host = *args; } else badarg = 1; } else if (!strcmp(*args, "-port")) { if (args[1]) { args++; port = *args; } else badarg = 1; } else if (!strcmp(*args, "-ignore_err")) ignore_err = 1; else if (!strcmp(*args, "-noverify")) noverify = 1; else if (!strcmp(*args, "-nonce")) add_nonce = 2; else if (!strcmp(*args, "-no_nonce")) add_nonce = 0; else if (!strcmp(*args, "-resp_no_certs")) rflags |= OCSP_NOCERTS; else if (!strcmp(*args, "-resp_key_id")) rflags |= OCSP_RESPID_KEY; else if (!strcmp(*args, "-no_certs")) sign_flags |= OCSP_NOCERTS; else if (!strcmp(*args, "-no_signature_verify")) verify_flags |= OCSP_NOSIGS; else if (!strcmp(*args, "-no_cert_verify")) verify_flags |= OCSP_NOVERIFY; else if (!strcmp(*args, "-no_chain")) verify_flags |= OCSP_NOCHAIN; else if (!strcmp(*args, "-no_cert_checks")) verify_flags |= OCSP_NOCHECKS; else if (!strcmp(*args, "-no_explicit")) verify_flags |= OCSP_NOEXPLICIT; else if (!strcmp(*args, "-trust_other")) verify_flags |= OCSP_TRUSTOTHER; else if (!strcmp(*args, "-no_intern")) verify_flags |= OCSP_NOINTERN; else if (!strcmp(*args, "-text")) { req_text = 1; resp_text = 1; } else if (!strcmp(*args, "-req_text")) req_text = 1; else if (!strcmp(*args, "-resp_text")) resp_text = 1; else if (!strcmp(*args, "-reqin")) { if (args[1]) { args++; reqin = *args; } else badarg = 1; } else if (!strcmp(*args, "-respin")) { if (args[1]) { args++; respin = *args; } else badarg = 1; } else if (!strcmp(*args, "-signer")) { if (args[1]) { args++; signfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-VAfile")) { if (args[1]) { args++; verify_certfile = *args; verify_flags |= OCSP_TRUSTOTHER; } else badarg = 1; } else if (!strcmp(*args, "-sign_other")) { if (args[1]) { args++; sign_certfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-verify_other")) { if (args[1]) { args++; verify_certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp (*args, "-validity_period")) { if (args[1]) { args++; nsec = atol(*args); if (nsec < 0) { BIO_printf(bio_err, "Illegal validity period %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-status_age")) { if (args[1]) { args++; maxage = atol(*args); if (maxage < 0) { BIO_printf(bio_err, "Illegal validity age %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-signkey")) { if (args[1]) { args++; keyfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-reqout")) { if (args[1]) { args++; reqout = *args; } else badarg = 1; } else if (!strcmp(*args, "-respout")) { if (args[1]) { args++; respout = *args; } else badarg = 1; } else if (!strcmp(*args, "-path")) { if (args[1]) { args++; path = *args; } else badarg = 1; } else if (!strcmp(*args, "-issuer")) { if (args[1]) { args++; X509_free(issuer); issuer = load_cert(bio_err, *args, FORMAT_PEM, NULL, e, "issuer certificate"); if(!issuer) goto end; } else badarg = 1; } else if (!strcmp (*args, "-cert")) { if (args[1]) { args++; X509_free(cert); cert = load_cert(bio_err, *args, FORMAT_PEM, NULL, e, "certificate"); if(!cert) goto end; if(!add_ocsp_cert(&req, cert, issuer, ids)) goto end; if(!sk_push(reqnames, *args)) goto end; } else badarg = 1; } else if (!strcmp(*args, "-serial")) { if (args[1]) { args++; if(!add_ocsp_serial(&req, *args, issuer, ids)) goto end; if(!sk_push(reqnames, *args)) goto end; } else badarg = 1; } else if (!strcmp(*args, "-index")) { if (args[1]) { args++; ridx_filename = *args; } else badarg = 1; } else if (!strcmp(*args, "-CA")) { if (args[1]) { args++; rca_filename = *args; } else badarg = 1; } else if (!strcmp (*args, "-nmin")) { if (args[1]) { args++; nmin = atol(*args); if (nmin < 0) { BIO_printf(bio_err, "Illegal update period %s\n", *args); badarg = 1; } } if (ndays == -1) ndays = 0; else badarg = 1; } else if (!strcmp (*args, "-nrequest")) { if (args[1]) { args++; accept_count = atol(*args); if (accept_count < 0) { BIO_printf(bio_err, "Illegal accept count %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-ndays")) { if (args[1]) { args++; ndays = atol(*args); if (ndays < 0) { BIO_printf(bio_err, "Illegal update period %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-rsigner")) { if (args[1]) { args++; rsignfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-rkey")) { if (args[1]) { args++; rkeyfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-rother")) { if (args[1]) { args++; rcertfile = *args; } else badarg = 1; } else badarg = 1; args++; } /* Have we anything to do? */ if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1; if (badarg) { BIO_printf (bio_err, "OCSP utility\n"); BIO_printf (bio_err, "Usage ocsp [options]\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-out file output filename\n"); BIO_printf (bio_err, "-issuer file issuer certificate\n"); BIO_printf (bio_err, "-cert file certificate to check\n"); BIO_printf (bio_err, "-serial n serial number to check\n"); BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n"); BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n"); BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n"); BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n"); BIO_printf (bio_err, "-req_text print text form of request\n"); BIO_printf (bio_err, "-resp_text print text form of response\n"); BIO_printf (bio_err, "-text print text form of request and response\n"); BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); BIO_printf (bio_err, "-nonce add OCSP nonce to request\n"); BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n"); BIO_printf (bio_err, "-url URL OCSP responder URL\n"); BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n"); BIO_printf (bio_err, "-path path to use in OCSP request\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-VAfile file validator certificates file\n"); BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); BIO_printf (bio_err, "-status_age n maximum status age in seconds\n"); BIO_printf (bio_err, "-noverify don't verify response at all\n"); BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n"); BIO_printf (bio_err, "-trust_other don't verify additional certificates\n"); BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n"); BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n"); BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n"); BIO_printf (bio_err, "-no_chain don't chain verify response\n"); BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); BIO_printf (bio_err, "-port num port to run responder on\n"); BIO_printf (bio_err, "-index file certificate status index file\n"); BIO_printf (bio_err, "-CA file CA certificate\n"); BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n"); BIO_printf (bio_err, "-rkey file responder key to sign responses with\n"); BIO_printf (bio_err, "-rother file other certificates to include in response\n"); BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n"); BIO_printf (bio_err, "-nmin n number of minutes before next update\n"); BIO_printf (bio_err, "-ndays n number of days before next update\n"); BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); goto end; } if(outfile) out = BIO_new_file(outfile, "w"); else out = BIO_new_fp(stdout, BIO_NOCLOSE); if(!out) { BIO_printf(bio_err, "Error opening output file\n"); goto end; } if (!req && (add_nonce != 2)) add_nonce = 0; if (!req && reqin) { derbio = BIO_new_file(reqin, "rb"); if (!derbio) { BIO_printf(bio_err, "Error Opening OCSP request file\n"); goto end; } req = d2i_OCSP_REQUEST_bio(derbio, NULL); BIO_free(derbio); if(!req) { BIO_printf(bio_err, "Error reading OCSP request\n"); goto end; } } if (!req && port) { acbio = init_responder(port); if (!acbio) goto end; } if (rsignfile && !rdb) { if (!rkeyfile) rkeyfile = rsignfile; rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM, NULL, e, "responder certificate"); if (!rsigner) { BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM, NULL, e, "CA certificate"); if (rcertfile) { rother = load_certs(bio_err, rcertfile, FORMAT_PEM, NULL, e, "responder other certificates"); if (!rother) goto end; } rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL, "responder private key"); if (!rkey) goto end; } if(acbio) BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); redo_accept: if (acbio) { if (!do_responder(&req, &cbio, acbio, port)) goto end; if (!req) { resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); send_ocsp_response(cbio, resp); goto done_resp; } } if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) { BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); goto end; } if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1); if (signfile) { if (!keyfile) keyfile = signfile; signer = load_cert(bio_err, signfile, FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) { BIO_printf(bio_err, "Error loading signer certificate\n"); goto end; } if (sign_certfile) { sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM, NULL, e, "signer certificates"); if (!sign_other) goto end; } key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL, "signer private key"); if (!key) goto end; if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags)) { BIO_printf(bio_err, "Error signing OCSP request\n"); goto end; } } if (req_text && req) OCSP_REQUEST_print(out, req, 0); if (reqout) { derbio = BIO_new_file(reqout, "wb"); if(!derbio) { BIO_printf(bio_err, "Error opening file %s\n", reqout); goto end; } i2d_OCSP_REQUEST_bio(derbio, req); BIO_free(derbio); } if (ridx_filename && (!rkey || !rsigner || !rca_cert)) { BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); goto end; } if (ridx_filename && !rdb) { rdb = load_index(ridx_filename, NULL); if (!rdb) goto end; if (!index_index(rdb)) goto end; } if (rdb) { i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays); if (cbio) send_ocsp_response(cbio, resp); } else if (host) { #ifndef OPENSSL_NO_SOCK cbio = BIO_new_connect(host); #else BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n"); goto end; #endif if (!cbio) { BIO_printf(bio_err, "Error creating connect BIO\n"); goto end; } if (port) BIO_set_conn_port(cbio, port); if (use_ssl == 1) { BIO *sbio; #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) ctx = SSL_CTX_new(SSLv23_client_method()); #elif !defined(OPENSSL_NO_SSL3) ctx = SSL_CTX_new(SSLv3_client_method()); #elif !defined(OPENSSL_NO_SSL2) ctx = SSL_CTX_new(SSLv2_client_method()); #else BIO_printf(bio_err, "SSL is disabled\n"); goto end; #endif if (ctx == NULL) { BIO_printf(bio_err, "Error creating SSL context.\n"); goto end; } SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); sbio = BIO_new_ssl(ctx, 1); cbio = BIO_push(sbio, cbio); } if (BIO_do_connect(cbio) <= 0) { BIO_printf(bio_err, "Error connecting BIO\n"); goto end; } resp = OCSP_sendreq_bio(cbio, path, req); BIO_free_all(cbio); cbio = NULL; if (!resp) { BIO_printf(bio_err, "Error querying OCSP responsder\n"); goto end; } } else if (respin) { derbio = BIO_new_file(respin, "rb"); if (!derbio) { BIO_printf(bio_err, "Error Opening OCSP response file\n"); goto end; } resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); BIO_free(derbio); if(!resp) { BIO_printf(bio_err, "Error reading OCSP response\n"); goto end; } } else { ret = 0; goto end; } done_resp: if (respout) { derbio = BIO_new_file(respout, "wb"); if(!derbio) { BIO_printf(bio_err, "Error opening file %s\n", respout); goto end; } i2d_OCSP_RESPONSE_bio(derbio, resp); BIO_free(derbio); } i = OCSP_response_status(resp); if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { BIO_printf(out, "Responder Error: %s (%d)\n", OCSP_response_status_str(i), i); if (ignore_err) goto redo_accept; ret = 0; goto end; } if (resp_text) OCSP_RESPONSE_print(out, resp, 0); /* If running as responder don't verify our own response */ if (cbio) { if (accept_count > 0) accept_count--; /* Redo if more connections needed */ if (accept_count) { BIO_free_all(cbio); cbio = NULL; OCSP_REQUEST_free(req); req = NULL; OCSP_RESPONSE_free(resp); resp = NULL; goto redo_accept; } goto end; } if (!store) store = setup_verify(bio_err, CAfile, CApath); if (!store) goto end; if (verify_certfile) { verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, NULL, e, "validator certificate"); if (!verify_other) goto end; } bs = OCSP_response_get1_basic(resp); if (!bs) { BIO_printf(bio_err, "Error parsing response\n"); goto end; } if (!noverify) { if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) { if (i == -1) BIO_printf(bio_err, "WARNING: no nonce in response\n"); else { BIO_printf(bio_err, "Nonce Verify error\n"); goto end; } } i = OCSP_basic_verify(bs, verify_other, store, verify_flags); if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); if(i <= 0) { BIO_printf(bio_err, "Response Verify Failure\n"); ERR_print_errors(bio_err); } else BIO_printf(bio_err, "Response verify OK\n"); } if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) goto end; ret = 0; end: ERR_print_errors(bio_err); X509_free(signer); X509_STORE_free(store); EVP_PKEY_free(key); EVP_PKEY_free(rkey); X509_free(issuer); X509_free(cert); X509_free(rsigner); X509_free(rca_cert); free_index(rdb); BIO_free_all(cbio); BIO_free_all(acbio); BIO_free(out); OCSP_REQUEST_free(req); OCSP_RESPONSE_free(resp); OCSP_BASICRESP_free(bs); sk_free(reqnames); sk_OCSP_CERTID_free(ids); sk_X509_pop_free(sign_other, X509_free); sk_X509_pop_free(verify_other, X509_free); if (use_ssl != -1) { OPENSSL_free(host); OPENSSL_free(port); OPENSSL_free(path); SSL_CTX_free(ctx); } OPENSSL_EXIT(ret); }
static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO *dbio; int *ip; const char **pptr; long ret=1; BIO_CONNECT *data; data=(BIO_CONNECT *)b->ptr; switch (cmd) { case BIO_CTRL_RESET: ret=0; data->state=BIO_CONN_S_BEFORE; conn_close_socket(b); b->flags=0; break; case BIO_C_DO_STATE_MACHINE: /* use this one to start the connection */ if (!data->state != BIO_CONN_S_OK) ret=(long)conn_state(b,data); else ret=1; break; case BIO_C_GET_CONNECT: if (ptr != NULL) { pptr=(const char **)ptr; if (num == 0) { *pptr=data->param_hostname; } else if (num == 1) { *pptr=data->param_port; } else if (num == 2) { *pptr= (char *)&(data->ip[0]); } else if (num == 3) { *((int *)ptr)=data->port; } if ((!b->init) || (ptr == NULL)) *pptr="not initialized"; ret=1; } break; case BIO_C_SET_CONNECT: if (ptr != NULL) { b->init=1; if (num == 0) { if (data->param_hostname != NULL) OPENSSL_free(data->param_hostname); data->param_hostname=BUF_strdup(ptr); } else if (num == 1) { if (data->param_port != NULL) OPENSSL_free(data->param_port); data->param_port=BUF_strdup(ptr); } else if (num == 2) { char buf[16]; unsigned char *p = ptr; BIO_snprintf(buf,sizeof buf,"%d.%d.%d.%d", p[0],p[1],p[2],p[3]); if (data->param_hostname != NULL) OPENSSL_free(data->param_hostname); data->param_hostname=BUF_strdup(buf); memcpy(&(data->ip[0]),ptr,4); } else if (num == 3) { char buf[DECIMAL_SIZE(int)+1]; BIO_snprintf(buf,sizeof buf,"%d",*(int *)ptr); if (data->param_port != NULL) OPENSSL_free(data->param_port); data->param_port=BUF_strdup(buf); data->port= *(int *)ptr; } } break; case BIO_C_SET_NBIO: data->nbio=(int)num; break; case BIO_C_GET_FD: if (b->init) { ip=(int *)ptr; if (ip != NULL) *ip=b->num; ret=b->num; } else ret= -1; break; case BIO_CTRL_GET_CLOSE: ret=b->shutdown; break; case BIO_CTRL_SET_CLOSE: b->shutdown=(int)num; break; case BIO_CTRL_PENDING: case BIO_CTRL_WPENDING: ret=0; break; case BIO_CTRL_FLUSH: break; case BIO_CTRL_DUP: { dbio=(BIO *)ptr; if (data->param_port) BIO_set_conn_port(dbio,data->param_port); if (data->param_hostname) BIO_set_conn_hostname(dbio,data->param_hostname); BIO_set_nbio(dbio,data->nbio); /* FIXME: the cast of the function seems unlikely to be a good idea */ (void)BIO_set_info_callback(dbio,(bio_info_cb *)data->info_callback); } break; case BIO_CTRL_SET_CALLBACK: { #if 0 /* FIXME: Should this be used? -- Richard Levitte */ BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ret = -1; #else ret=0; #endif } break; case BIO_CTRL_GET_CALLBACK: { int (**fptr)(); fptr=(int (**)())ptr; *fptr=data->info_callback; } break; default: ret=0; break; } return(ret); }
/** * Run SSL handshake and store the resulting time value in the * 'time_map'. * * @param time_map where to store the current time */ static void run_ssl (uint32_t *time_map) { BIO *s_bio; BIO *c_bio; SSL_CTX *ctx; SSL *ssl; SSL_load_error_strings(); SSL_library_init(); ctx = NULL; if (0 == strcmp("sslv23", protocol)) { verb ("V: using SSLv23_client_method()\n"); ctx = SSL_CTX_new(SSLv23_client_method()); } else if (0 == strcmp("sslv3", protocol)) { verb ("V: using SSLv3_client_method()\n"); ctx = SSL_CTX_new(SSLv3_client_method()); } else if (0 == strcmp("tlsv1", protocol)) { verb ("V: using TLSv1_client_method()\n"); ctx = SSL_CTX_new(TLSv1_client_method()); } else die("Unsupported protocol `%s'\n", protocol); if (ctx == NULL) die("OpenSSL failed to support protocol `%s'\n", protocol); if (ca_racket) { // For google specifically: // SSL_CTX_load_verify_locations(ctx, "/etc/ssl/certs/Equifax_Secure_CA.pem", NULL); if (1 != SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs/")) fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); } if (NULL == (s_bio = BIO_new_ssl_connect(ctx))) die ("SSL BIO setup failed\n"); BIO_get_ssl(s_bio, &ssl); if (NULL == ssl) die ("SSL setup failed\n"); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); if ( (1 != BIO_set_conn_hostname(s_bio, host)) || (1 != BIO_set_conn_port(s_bio, port)) ) die ("Failed to initialize connection to `%s:%s'\n", host, port); if (NULL == (c_bio = BIO_new_fp(stdout, BIO_NOCLOSE))) die ("FIXME: error message"); // This should run in seccomp // eg: prctl(PR_SET_SECCOMP, 1); if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later? die ("SSL connection failed\n"); if (1 != BIO_do_handshake(s_bio)) die ("SSL handshake failed\n"); // Verify the peer certificate against the CA certs on the local system if (ca_racket) { X509 *x509; long ssl_verify_result; if (NULL == (x509 = SSL_get_peer_certificate(ssl)) ) die ("Getting SSL certificate failed\n"); // In theory, we verify that the cert is valid ssl_verify_result = SSL_get_verify_result(ssl); switch (ssl_verify_result) { case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: die ("SSL certificate is self signed\n"); case X509_V_OK: verb ("V: SSL certificate verification passed\n"); break; default: die ("SSL certification verification error: %ld\n", ssl_verify_result); } } else { verb ("V: Certificate verification skipped!\n"); } // from /usr/include/openssl/ssl3.h // ssl->s3->server_random is an unsigned char of 32 bytes memcpy(time_map, ssl->s3->server_random, sizeof (uint32_t)); }
int main(int argc, char **argv) { BIO *sslbio; SSL_CTX *ctx; SSL *ssl; //SSL_METHOD *meth; unsigned long totl; int i, p; char hostname[BUF_SIZE + 1]; char server[16]; char choice; int ret; if (argc != 2) { printf("Usage: %s ClientName\n", argv[0]); printf("eg: '%s client1'\n", argv[0]); return -1; } if (strlen(argv[1]) >= NAME_SIZE) { fprintf(stderr, "%s is too long! \nPick a shorter client name.\n",argv[1]); } else { strcpy(CLIENT_NAME, argv[1]); } printf("client name: %s\n", CLIENT_NAME); /* Formatting required certificates for client ... certificates are matched to client with file names */ int length = strlen(CLIENT_NAME) + 10; char CLIENT_CERT_FILE2[length]; strcpy(CLIENT_CERT_FILE2, "cert/"); strcat(CLIENT_CERT_FILE2, CLIENT_NAME); strcat(CLIENT_CERT_FILE2, ".pem"); printf("This client CERT file is required: %s\n", CLIENT_CERT_FILE2); // Checking for required certificate if( access( CLIENT_CERT_FILE2, F_OK ) != -1 ) { // file exists printf("CERT file verified present\n"); } else { // file doesn't exist printf("CERT NOT FOUND....\n" "Perhaps this client does not have valid\n" "certificates present at this location\n" ">>> ./%s\n",CLIENT_CERT_FILE2); exit(4); } char CLIENT_KEY_FILE2[length]; strcpy(CLIENT_KEY_FILE2, "cert/"); strcat(CLIENT_KEY_FILE2, CLIENT_NAME); strcat(CLIENT_KEY_FILE2, ".key"); printf("This client KEY file is required: %s\n", CLIENT_KEY_FILE2); // Checking for required certificate if( access( CLIENT_KEY_FILE2, F_OK ) != -1 ) { // file exists printf("KEY file verified present\n\n"); } else { // file doesn't exist printf("KEY NOT FOUND....\n" "Perhaps this client does not have valid" "certificates present at this location\n" ">>> ./%s\n",CLIENT_KEY_FILE2); exit(4); } /* Give initial menu to user; get hostname for connection */ choice = getchoice("Please select an action", imenu); printf("You have chosen: %c\n", choice); if (choice == 'q') { printf("Ending Program... Goodbye.\n"); } else // choice == 'a' { printf("Initializing connection...\n"); // NOTE: 45 is the max length of a IPv4 address getInput(server, "Enter server hostname to connect \n (e.g., '127.0.0.1')", 15); SSL_library_init(); ERR_load_BIO_strings(); ERR_load_SSL_strings(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); ctx = SSL_CTX_new(SSLv3_client_method()); // ctx = SSL_CTX_new(SSLv3_method()); //ctx = SSL_CTX_new(meth); assert(ctx != NULL); /* Verify the server */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); /* Load CA Certificate */ if (!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL)) { printf("Load CA file failed.\r\n"); //goto free_ctx; BIO_free_all(sslbio); SSL_CTX_free(ctx); return 0; } /* Load Client Certificate with Public Key */ if (SSL_CTX_use_certificate_file(ctx, CLIENT_CERT_FILE2, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stdout); printf("ssl_ctx_use_certificate_file failed.\r\n"); //goto free_ctx; BIO_free_all(sslbio); SSL_CTX_free(ctx); return 0; } /* Load Private Key */ if (SSL_CTX_use_PrivateKey_file(ctx, CLIENT_KEY_FILE2, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stdout); printf("ssl_ctx_use_privatekey_file failed.\r\n"); //goto free_ctx; BIO_free_all(sslbio); SSL_CTX_free(ctx); return 0; } /* Check the validity of Private Key */ if (!SSL_CTX_check_private_key(ctx)) { ERR_print_errors_fp(stdout); printf("ssl_ctx_check_private_key failed.\r\n"); //goto free_ctx; BIO_free_all(sslbio); SSL_CTX_free(ctx); return 0; } /* Create the connection */ sslbio = BIO_new_ssl_connect(ctx); /* Get SSL from sslbio */ BIO_get_ssl(sslbio, &ssl); /* Set the SSL mode into SSL_MODE_AUTO_RETRY */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); ////////////////////////////////////////////////// // NOTE: Port# hardcoded here; change if necessary ////////////////////////////////////////////////// BIO_set_conn_port(sslbio, "7777"); BIO_set_conn_hostname(sslbio, server); /* Request Connection */ if(BIO_do_connect(sslbio) <= 0) { fprintf(stderr, "Error attempting to connect\n"); ERR_print_errors_fp(stderr); BIO_free_all(sslbio); SSL_CTX_free(ctx); return 0; } else { printf("Connection to server successful!\n"); } /* Verify Server Certificate Validity */ if(SSL_get_verify_result(ssl) != X509_V_OK) { printf("Certificate Verification Error: %ld\n", SSL_get_verify_result(ssl)); BIO_free_all(sslbio); SSL_CTX_free(ctx); return 0; } else { printf("verify server cert successful\n"); } //Send hostname to server printf("Sending client name to server.\n"); BIO_write(sslbio, CLIENT_NAME, strlen(CLIENT_NAME)); do { choice = getchoice("Please select an action", menu); printf("You have chosen: %c\n", choice); if (choice == 'a') { printf("Check-in function will be executed\n"); choiceProcess (sslbio, buffer, choice); ret = checkin_file(ssl, sslbio, buffer); } else if (choice == 'b') { printf("Check-out function will be executed\n"); choiceProcess (sslbio, buffer, choice); ret = checkout_file(ssl, sslbio, buffer); } else if (choice == 'c') { printf("Delegate function will be executed\n"); choiceProcess (sslbio, buffer, choice); } else if (choice == 'd') { printf("Safe-delete function will be executed\n"); choiceProcess (sslbio, buffer, choice); } else { printf("Terminate function will be executed\n"); } } while (choice != 'q'); /* Terminate the connection by sending message */ clientTerminate (sslbio, buffer); /* Close the connection and free the context */ BIO_ssl_shutdown(sslbio); BIO_free_all(sslbio); SSL_CTX_free(ctx); } return 0; }
/** Returns status of ticket by filling 'buf' with a NetID if the ticket * is valid and buf is large enough and returning 1. If not, 0 is * returned. */ int cas_validate( char *ticket, char *service, char *outbuf, int outbuflen, pam_cas_config_t *config) { int b, ret, total; SSL_CTX *ctx = NULL; BIO * bio = NULL; SSL *ssl = NULL; char buf[4096]; char *full_request = NULL, *str; char netid[CAS_LEN_NETID]; char parsebuf[128]; debug = config->debug; if (config->ssl) { DEBUG_LOG("We use SSL as configured\n", ""); /* Set up the SSL library */ ERR_load_BIO_strings(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); #if defined(OpenSSL_add_ssl_algorithms) OpenSSL_add_ssl_algorithms(); #endif /* Set up the SSL context */ ctx = SSL_CTX_new(SSLv23_client_method()); if ( ! ctx ) { DEBUG_LOG("Cannot create SSL context", ""); END(CAS_SSL_ERROR_INIT); } /* Load the trust store */ if(! SSL_CTX_load_verify_locations(ctx, config->trusted_ca, NULL)) { DEBUG_LOG("Error loading certificate store : %s\n", ERR_reason_error_string(ERR_get_error())); END(CAS_SSL_ERROR_CERT_LOAD); } /* Setup the connection */ bio = BIO_new_ssl_connect(ctx); /* Set the SSL_MODE_AUTO_RETRY flag : if the server suddenly wants a new handshake, OpenSSL handles it in the background */ BIO_get_ssl(bio, & ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* Create and setup the connection */ DEBUG_LOG("We connect to host %s\n", config->host); BIO_set_conn_hostname(bio, config->host); BIO_set_conn_port(bio, config->port); if(BIO_do_connect(bio) <= 0) { DEBUG_LOG("Error attempting to connect : %s\n", ERR_reason_error_string(ERR_get_error())); END(CAS_SSL_ERROR_CONN); } /* Check the certificate */ if (SSL_get_verify_result(ssl) != X509_V_OK) { DEBUG_LOG("Certificate verification error: %ld\n", SSL_get_verify_result(ssl)); END(CAS_SSL_ERROR_CERT_VALID); } } else /* no ssl */ { bio = BIO_new_connect(config->host); BIO_set_conn_port(bio, config->port); if(BIO_do_connect(bio) <= 0) { DEBUG_LOG("Error attempting to connect : %s\n", config->host); END(CAS_ERROR_CONN); } } /* build request */ full_request = malloc(strlen(CAS_METHOD) + strlen(" ") + strlen(config->uriValidate) + strlen("?ticket=") + strlen(ticket) + + strlen("&service=") + strlen(service) + strlen(" ") + strlen(GENERIC_HEADERS) + strlen ("\r\n") #ifdef HEADER_HOST_NAME + strlen(HEADER_HOST_NAME) + strlen (": ") + strlen (config->host) #endif + strlen("\r\n\r\n") + 1); if (full_request == NULL) { DEBUG_LOG("Error memory allocation%s\n", ""); END(CAS_ERROR_MEMORY_ALLOC); } #ifdef HEADER_HOST_NAME sprintf(full_request, "%s %s?ticket=%s&service=%s %s\r\n%s: %s\r\n\r\n", CAS_METHOD, config->uriValidate, ticket, service, GENERIC_HEADERS, HEADER_HOST_NAME,config->host); #else sprintf(full_request, "%s %s?ticket=%s&service=%s %s\r\n\r\n", CAS_METHOD, config->uriValidate, ticket, service, GENERIC_HEADERS); #endif /* send request */ DEBUG_LOG("---- request :\n%s\n", full_request); if (BIO_write(bio, full_request, strlen(full_request)) != strlen(full_request)) { DEBUG_LOG("Unable to correctly send request to %s\n", config->host); END(CAS_ERROR_HTTP); } /* Read the response */ total = 0; b = 0; do { b = BIO_read(bio, buf + total, (sizeof(buf) - 1) - total); total += b; } while (b > 0); buf[total] = '\0'; if (b != 0 || total >= sizeof(buf) - 1) { DEBUG_LOG("Unexpected read error or response too large from %s\n", config->host); DEBUG_LOG("b = %d\n", b); DEBUG_LOG("total = %d\n", total); DEBUG_LOG("buf = %s\n", buf); END(CAS_ERROR_HTTP); // unexpected read error or response too large } DEBUG_LOG("---- response :\n%s\n", buf); str = (char *)strstr(buf, "\r\n\r\n"); // find the end of the header if (!str) { DEBUG_LOG("no header in response%s\n", ""); END(CAS_ERROR_HTTP); // no header } /* * 'str' now points to the beginning of the body, which should be an * XML document */ // make sure that the authentication succeeded if (!element_body( str, "cas:authenticationSuccess", 1, parsebuf, sizeof(parsebuf))) { END(CAS_BAD_TICKET); } // retrieve the NetID if (!element_body(str, "cas:user", 1, netid, sizeof(netid))) { DEBUG_LOG("unable to determine username%s\n", ""); END(CAS_PROTOCOL_FAILURE); } // check the first proxy (if present) if ((config->proxies) && (config->proxies[0])) if (element_body(str, "cas:proxies", 1, parsebuf, sizeof(parsebuf))) if (element_body(str, "cas:proxy", 1, parsebuf, sizeof(parsebuf))) if (!arrayContains(config->proxies, parsebuf)) { DEBUG_LOG("bad proxy: %s\n", parsebuf); END(CAS_BAD_PROXY); } /* * without enough space, fail entirely, since a partial NetID could * be dangerous */ if (outbuflen < strlen(netid) + 1) { syslog(LOG_ERR, "output buffer too short"); DEBUG_LOG("output buffer too short%s\n", ""); END(CAS_PROTOCOL_FAILURE); } strcpy(outbuf, netid); SUCCEED; /* cleanup and return */ end: if (ctx) SSL_CTX_free(ctx); if (bio) BIO_free_all(bio); if (full_request) free(full_request); return ret; }
int main(int argc, char **argv) { SSL_load_error_strings(); ERR_load_BIO_strings(); SSL_library_init(); /*BIO *SSLout = BIO_new_connect(BROKER_CONN); if (!SSLout) { fprintf(stderr, "Error creating BIO\n"); exit(EXIT_FAILURE); } if (BIO_do_connect(SSLout) <= 0) { fprintf(stderr,"Error connecting BIO\n"); exit(EXIT_FAILURE); } char buf[BUFSIZ]; */ printf("HERE\n"); SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); if (!SSL_CTX_load_verify_locations(ctx,BROKER_CERT,NULL)) { fprintf(stderr,"Failed to load broker cert\n"); exit(EXIT_FAILURE); } printf("HERE\n"); SSL *ssl = SSL_new(ctx); SSL_set_mode(ssl,SSL_MODE_AUTO_RETRY); BIO *sslconn = BIO_new_ssl_connect(ctx); BIO_get_ssl(sslconn, &ssl); printf("HERE\n"); // Do connection BIO_set_conn_hostname(sslconn,BROKER_CONN); BIO_set_conn_port(sslconn,BROKER_PORT); if (BIO_do_connect(sslconn) < 0) { fprintf(stderr,"Failed to make ssl connection\n"); fprintf(stderr,"Error description: %s\n", ERR_reason_error_string(ERR_get_error())); exit(EXIT_FAILURE); } int err; if((err = SSL_connect(ssl)) < 1) { fprintf(stderr, "Failed to initiate handshake:%s\n", ERR_reason_error_string(ERR_get_error())); } printf("HERE\n"); char buf[BUFSIZ]; strcpy(buf,"OHAITHAR!\n"); if( BIO_write(sslconn,buf,strlen(buf)) <= 0 ) { if(! BIO_should_retry(sslconn)) { } } /*if we want to reuse, start fresh BIO_reset(sslconn); */ BIO_free_all(sslconn); return 0; }
/* * Establishes the connection to the Duo server. On successful return, * req->cbio is connected and ready to use. * Return HTTPS_OK on success, error code on failure. */ static HTTPScode _establish_connection(struct https_request * const req, const char * const api_host, const char * const api_port) { #ifndef HAVE_GETADDRINFO /* Systems that don't have getaddrinfo can use the BIO wrappers, but only get IPv4 support. */ int n; if ((req->cbio = BIO_new(BIO_s_connect())) == NULL) { ctx->errstr = _SSL_strerror(); return HTTPS_ERR_LIB; } BIO_set_conn_hostname(req->cbio, api_host); BIO_set_conn_port(req->cbio, api_port); BIO_set_nbio(req->cbio, 1); while (BIO_do_connect(req->cbio) <= 0) { if ((n = _BIO_wait(req->cbio, 10000)) != 1) { ctx->errstr = n ? _SSL_strerror() : "Connection timed out"; return (n ? HTTPS_ERR_SYSTEM : HTTPS_ERR_SERVER); } } return HTTPS_OK; #else /* HAVE_GETADDRINFO */ /* IPv6 Support * BIO wrapped io does not support IPv6 addressing. To work around, * resolve the address and connect the socket manually. Then pass * the connected socket to the BIO wrapper with BIO_new_socket. */ int connected_socket = -1; int socket_error = 0; /* Address Lookup */ struct addrinfo *res = NULL; struct addrinfo *cur_res = NULL; struct addrinfo hints; int error; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(api_host, api_port, &hints, &res); if (error) { ctx->errstr = gai_strerror(error); return HTTPS_ERR_SYSTEM; } /* Connect */ for (cur_res = res; cur_res; cur_res = cur_res->ai_next) { int connretries = 3; while (connected_socket == -1 && connretries--) { int sock_flags; connected_socket = socket(cur_res->ai_family, cur_res->ai_socktype, cur_res->ai_protocol); if (connected_socket == -1) { continue; } sock_flags = fcntl(connected_socket, F_GETFL, 0); fcntl(connected_socket, F_SETFL, sock_flags|O_NONBLOCK); if (connect(connected_socket, cur_res->ai_addr, cur_res->ai_addrlen) != 0 && errno != EINPROGRESS) { close(connected_socket); connected_socket = -1; break; } socket_error = _fd_wait(connected_socket, 10000); if (socket_error != 1) { close(connected_socket); connected_socket = -1; continue; } /* Connected! */ break; } } cur_res = NULL; freeaddrinfo(res); res = NULL; if (connected_socket == -1) { ctx->errstr = "Failed to connect"; return socket_error ? HTTPS_ERR_SYSTEM : HTTPS_ERR_SERVER; } if ((req->cbio = BIO_new_socket(connected_socket, BIO_CLOSE)) == NULL) { ctx->errstr = _SSL_strerror(); return (HTTPS_ERR_LIB); } BIO_set_conn_hostname(req->cbio, api_host); BIO_set_conn_port(req->cbio, api_port); BIO_set_nbio(req->cbio, 1); return HTTPS_OK; #endif /* HAVE_GETADDRINFO */ }
enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t *pb) { SSL *ssl = NULL; int rslt; char const* origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); PUBNUB_ASSERT_OPT((pb->state == PBS_READY) || (pb->state == PBS_WAIT_CONNECT)); if (!pb->options.useSSL) { return resolv_and_connect_wout_SSL(pb); } if (NULL == pb->pal.ctx) { PUBNUB_LOG_TRACE("pb=%p: Don't have SSL_CTX\n", pb); pb->pal.ctx = SSL_CTX_new(SSLv23_client_method()); if (NULL == pb->pal.ctx) { ERR_print_errors_cb(print_to_pubnub_log, NULL); PUBNUB_LOG_ERROR("pb=%p SSL_CTX_new failed\n", pb); return pbpal_resolv_resource_failure; } PUBNUB_LOG_TRACE("pb=%p: Got SSL_CTX\n", pb); add_pubnub_cert(pb->pal.ctx); } if (NULL == pb->pal.socket) { PUBNUB_LOG_TRACE("pb=%p: Don't have BIO\n", pb); pb->pal.socket = BIO_new_ssl_connect(pb->pal.ctx); if (PUBNUB_TIMERS_API) { pb->pal.connect_timeout = time(NULL) + pb->transaction_timeout_ms/1000; } } else { BIO_get_ssl(pb->pal.socket, &ssl); if (NULL == ssl) { return resolv_and_connect_wout_SSL(pb); } ssl = NULL; } if (NULL == pb->pal.socket) { ERR_print_errors_cb(print_to_pubnub_log, NULL); return pbpal_resolv_resource_failure; } PUBNUB_LOG_TRACE("pb=%p: Using BIO == %p\n", pb, pb->pal.socket); BIO_get_ssl(pb->pal.socket, &ssl); PUBNUB_ASSERT(NULL != ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* maybe not auto_retry? */ if (pb->pal.session != NULL) { SSL_set_session(ssl, pb->pal.session); } BIO_set_conn_hostname(pb->pal.socket, origin); BIO_set_conn_port(pb->pal.socket, "https"); if (pb->pal.ip_timeout != 0) { if (pb->pal.ip_timeout < time(NULL)) { pb->pal.ip_timeout = 0; } else { PUBNUB_LOG_TRACE("SSL re-connect to: %d.%d.%d.%d\n", pb->pal.ip[0], pb->pal.ip[1], pb->pal.ip[2], pb->pal.ip[3]); BIO_set_conn_ip(pb->pal.socket, pb->pal.ip); } } BIO_set_nbio(pb->pal.socket, !pb->options.use_blocking_io); WATCH_ENUM(pb->options.use_blocking_io); if (BIO_do_connect(pb->pal.socket) <= 0) { if (BIO_should_retry(pb->pal.socket) && PUBNUB_TIMERS_API && (pb->pal.connect_timeout > time(NULL))) { PUBNUB_LOG_TRACE("pb=%p: BIO_should_retry\n", pb); return pbpal_connect_wouldblock; } /* Expire the IP for the next connect */ pb->pal.ip_timeout = 0; ERR_print_errors_cb(print_to_pubnub_log, NULL); if (pb->pal.session != NULL) { SSL_SESSION_free(pb->pal.session); pb->pal.session = NULL; } PUBNUB_LOG_ERROR("pb=%p: BIO_do_connect failed\n", pb); return pbpal_connect_failed; } PUBNUB_LOG_TRACE("pb=%p: BIO connected\n", pb); { int fd = BIO_get_fd(pb->pal.socket, NULL); socket_set_rcv_timeout(fd, pb->transaction_timeout_ms); } rslt = SSL_get_verify_result(ssl); if (rslt != X509_V_OK) { PUBNUB_LOG_WARNING("pb=%p: SSL_get_verify_result() failed == %d(%s)\n", pb, rslt, X509_verify_cert_error_string(rslt)); ERR_print_errors_cb(print_to_pubnub_log, NULL); if (pb->options.fallbackSSL) { BIO_free_all(pb->pal.socket); pb->pal.socket = NULL; return resolv_and_connect_wout_SSL(pb); } return pbpal_connect_failed; } PUBNUB_LOG_INFO("pb=%p: SSL session reused: %s\n", pb, SSL_session_reused(ssl) ? "yes" : "no"); if (pb->pal.session != NULL) { SSL_SESSION_free(pb->pal.session); } pb->pal.session = SSL_get1_session(ssl); if (0 == pb->pal.ip_timeout) { pb->pal.ip_timeout = SSL_SESSION_get_time(pb->pal.session) + SSL_SESSION_get_timeout(pb->pal.session); memcpy(pb->pal.ip, BIO_get_conn_ip(pb->pal.socket), 4); } PUBNUB_LOG_TRACE("pb=%p: SSL connected to IP: %d.%d.%d.%d\n", pb, pb->pal.ip[0], pb->pal.ip[1], pb->pal.ip[2], pb->pal.ip[3]); return pbpal_connect_success; }