BIO *Connect_SSL(char *hostname, int port) { //BIO *bio = NULL; char bio_addr[BUF_MAX] = { 0 }; snprintf(bio_addr, sizeof(bio_addr), "%s:%d", hostname, port); SSL_library_init(); SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); SSL *ssl = NULL; bio = BIO_new_ssl_connect(ctx); if (bio == NULL) { Error("BIO_new_ssl_connect"); } BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); BIO_set_conn_hostname(bio, bio_addr); if (BIO_do_connect(bio) <= 0) { Error("SSL Unable to connect"); } return bio; }
BIO* connect_encrypted(char* host_and_port, char* store_path, char store_type, SSL_CTX** ctx, SSL** ssl) { BIO* bio = NULL; int r = 0; *ctx = SSL_CTX_new(SSLv23_client_method()); *ssl = NULL; if (store_type == 'f') r = SSL_CTX_load_verify_locations(*ctx, store_path, NULL); else r = SSL_CTX_load_verify_locations(*ctx, NULL, store_path); if (r == 0) { return NULL; } bio = BIO_new_ssl_connect(*ctx); BIO_get_ssl(bio, ssl); if (!(*ssl)) { return NULL; } SSL_set_mode(*ssl, SSL_MODE_AUTO_RETRY); BIO_set_conn_hostname(bio, host_and_port); if (BIO_do_connect(bio) < 1) { return NULL; } return bio; }
static Pfd* opensslconnect(char *host) { Pfd *pfd; BIO *sbio; SSL_CTX *ctx; SSL *ssl; static int didinit; char buf[1024]; if(!didinit){ httpsinit(); didinit = 1; } ctx = SSL_CTX_new(SSLv23_client_method()); sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); snprint(buf, sizeof buf, "%s:https", host); BIO_set_conn_hostname(sbio, buf); if(BIO_do_connect(sbio) <= 0 || BIO_do_handshake(sbio) <= 0){ ERR_error_string_n(ERR_get_error(), buf, sizeof buf); BIO_free_all(sbio); werrstr("openssl: %s", buf); return nil; } pfd = emalloc(sizeof *pfd); pfd->sbio = sbio; return pfd; }
int main() { SSL_load_error_strings(); ERR_load_BIO_strings(); OpenSSL_add_all_algorithms(); SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { printf("SSL_CTX_new err func:%s\n reaseon:%s", ERR_func_error_string(ERR_get_error()), ERR_reason_error_string(ERR_get_error())); exit(1); } //加载可信任证书库 if (0 == SSL_CTX_load_verify_locations(ctx, "./push_cer.pem", NULL)) { printf("err func:%s\n reaseon:%s", ERR_func_error_string(ERR_get_error()), ERR_reason_error_string(ERR_get_error())); ERR_print_errors_fp(stdout); exit(1); } //set BIO BIO *bio = BIO_new_ssl_connect(ctx); if (bio == NULL) { printf("err func:%s\n", ERR_func_error_string(ERR_get_error())); ERR_print_errors_fp(stdout); exit(1); } SSL *ssl; BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); //open safe connect BIO_set_conn_hostname(bio, "gateway.sandbox.push.apple.com:2195"); //verify connect ok if (BIO_do_connect(bio) <= 0) { ERR_print_errors_fp(stdout); exit(1); } if (SSL_get_verify_result(ssl) != X509_V_OK) { printf("SSL_get_verify_result not success\n"); } char buf[MAXBUF]; char *json = "{\"aps\":{\"badge\":123}}"; sendPayload(bio, token, json, strlen(json)); int ret = BIO_read(bio, buf, MAXBUF); if (ret <= 0) { printf("BIO_read return 0\n"); } SSL_CTX_free(ctx); BIO_free_all(bio); return 0; }
bool Email::sendCode(std::string user, std::string code) { std::string msg,to; msg = m_m1 + code + m_m2; to = m_to1 + user + m_to3; SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method()); SSL* ssl; BIO* bio = BIO_new_ssl_connect(ctx); BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); BIO_set_conn_hostname(bio, m_amazonHostname.c_str()); if(BIO_do_connect(bio) <= 0){ BIO_free_all(bio); SSL_CTX_free(ctx); return false; } if(BIO_do_handshake(bio) <= 0){ BIO_free_all(bio); SSL_CTX_free(ctx); return false; } m_len = BIO_read(bio, m_buf, BUF_LEN) - 1; BIO_puts(bio, "HELO localhost\r\n"); m_len = BIO_read(bio, m_buf, BUF_LEN) - 1; BIO_puts(bio,"AUTH LOGIN\r\n"); m_len = BIO_read(bio,m_buf,BUF_LEN) - 1; BIO_puts(bio,"QUtJQUlFVzJDMlU3RUZYTU5PUVE=\r\n"); m_len = BIO_read(bio,m_buf,BUF_LEN) - 1; BIO_puts(bio,"QWd3TkZSOUJyb2dUTUkxYlJHeXh4dHZMYm4reldGZCtYSFJMbnJpNzZ5RC8=\r\n"); m_len = BIO_read(bio,m_buf,BUF_LEN) - 1; BIO_puts(bio,"MAIL FROM:[email protected]\r\n"); m_len = BIO_read(bio,m_buf,BUF_LEN) - 1; BIO_puts(bio,to.c_str()); m_len = BIO_read(bio,m_buf,BUF_LEN) - 1; BIO_puts(bio,"DATA\r\n"); m_len = BIO_read(bio,m_buf,BUF_LEN) - 1; BIO_puts(bio,"Subject:OneBrown Verification\r\n\r\n"); BIO_puts(bio,msg.c_str()); BIO_puts(bio,"\r\n.\r\n"); m_len = BIO_read(bio,m_buf,BUF_LEN) - 1; BIO_puts(bio,"QUIT\r\n"); m_len = BIO_read(bio,m_buf,BUF_LEN) - 1; BIO_free_all(bio); SSL_CTX_free(ctx); return true; }
const char *dbapi_lookup(const char *key) { long res = 1; SSL_CTX* ctx = NULL; BIO *web = NULL, *out = NULL; SSL *ssl = NULL; const SSL_METHOD* method; char *token, *tmpout, *buf; int hlen=0, len=0, maxlen=2048; (void)SSL_library_init(); SSL_load_error_strings(); OPENSSL_config(NULL); method = SSLv23_method(); if(method==NULL) return NULL; ctx = SSL_CTX_new(method); if(ctx==NULL) return NULL; SSL_CTX_set_verify_depth(ctx, 4); SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1| SSL_OP_NO_COMPRESSION); web = BIO_new_ssl_connect(ctx); if(web==NULL) return NULL; res = BIO_set_conn_hostname(web, DB_API_SERVER); if(res!=1) return NULL; BIO_get_ssl(web, &ssl); if(ssl==NULL) return NULL; res = SSL_set_cipher_list(ssl, SECURE_CIPHER_LIST); if(res!=1) return NULL; res = SSL_set_tlsext_host_name(ssl, DB_API_HOST); if(res!=1) return NULL; out = BIO_new_fp(stdout, BIO_NOCLOSE); if(NULL==out) return NULL; res = BIO_do_connect(web); if(res!=1) return NULL; res = BIO_do_handshake(web); if(res!=1) return NULL; len=(60+strlen(key)+strlen(DB_API_HOST)+strlen(DB_API_AUTH)); char *request=malloc(sizeof(char)*(len+1)); snprintf(request,len, "GET %s HTTP/1.1\nHost: %s\nx-api-key: %s\nConnection: close\n\n", key, DB_API_HOST, DB_API_AUTH); request[len]='\0'; BIO_puts(web, request); BIO_puts(out, "\n"); buf = malloc(sizeof(char)*maxlen); do { char buff[1536] = {}; len=BIO_read(web, buff, sizeof(buff)); hlen+=len; if(hlen<maxlen&&len>0) strncat(buf,buff,len); } while (len>0 || BIO_should_retry(web)); buf[maxlen]='\0'; tmpout = malloc(sizeof(char)*(HASH_MAXLENGTH+1)); token = strtok(buf, "\n"); while (token) { snprintf(tmpout,HASH_MAXLENGTH,"%s",token); token = strtok(NULL, "\n"); } tmpout[strlen(tmpout)]='\0'; free(buf); free(request); if(out) BIO_free(out); if(web != NULL) BIO_free_all(web); if(NULL != ctx) SSL_CTX_free(ctx); return tmpout; }
static BIO * my_connect_ssl(char *host, int port, SSL_CTX **ctx) { BIO *conn = 0; if (!(conn = BIO_new_ssl_connect(*ctx))) goto error_exit; BIO_set_conn_hostname(conn, host); BIO_set_conn_int_port(conn, &port); if (BIO_do_connect(conn) <= 0) goto error_exit; return conn; error_exit: if (conn) BIO_free_all(conn); return 0; }
/** * Connect to a host using an encrypted stream */ BIO* connect_encrypted(char* host_and_port, char* store_path, char store_type, SSL_CTX** ctx, SSL** ssl) { BIO* bio = NULL; int r = 0; /* Set up the SSL pointers */ *ctx = SSL_CTX_new(SSLv23_client_method()); *ssl = NULL; /* Load the trust store from the pem location in argv[2] */ if (store_type == 'f') r = SSL_CTX_load_verify_locations(*ctx, store_path, NULL); else r = SSL_CTX_load_verify_locations(*ctx, NULL, store_path); if (r == 0) { print_ssl_error_2("Unable to load the trust store from %s.\n", store_path, stdout); return NULL; } /* Setting up the BIO SSL object */ bio = BIO_new_ssl_connect(*ctx); BIO_get_ssl(bio, ssl); if (!(*ssl)) { print_ssl_error("Unable to allocate SSL pointer.\n", stdout); return NULL; } SSL_set_mode(*ssl, SSL_MODE_AUTO_RETRY); /* Attempt to connect */ BIO_set_conn_hostname(bio, host_and_port); /* Verify the connection opened and perform the handshake */ if (BIO_do_connect(bio) < 1) { print_ssl_error_2("Unable to connect BIO.%s\n", host_and_port, stdout); return NULL; } if (SSL_get_verify_result(*ssl) != X509_V_OK) { print_ssl_error("Unable to verify connection result.\n", stdout); } return bio; }
bool tls_socket::set_hostname(const char* sAddr) { sock_closed = false; if(ctx == nullptr) { init_ctx(); if(ctx == nullptr) { print_error(); return false; } } if((bio = BIO_new_ssl_connect(ctx)) == nullptr) { print_error(); return false; } int flag = 1; /* If it fails, it fails, we won't loose too much sleep over it */ setsockopt(BIO_get_fd(bio, nullptr), IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); if(BIO_set_conn_hostname(bio, sAddr) != 1) { print_error(); return false; } BIO_get_ssl(bio, &ssl); if(ssl == nullptr) { print_error(); return false; } if(jconf::inst()->TlsSecureAlgos()) { if(SSL_set_cipher_list(ssl, "HIGH:!aNULL:!PSK:!SRP:!MD5:!RC4:!SHA1") != 1) { print_error(); return false; } } return true; }
BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) { #ifndef OPENSSL_NO_SOCK BIO *ret=NULL,*buf=NULL,*ssl=NULL; if ((buf=BIO_new(BIO_f_buffer())) == NULL) return(NULL); if ((ssl=BIO_new_ssl_connect(ctx)) == NULL) goto err; if ((ret=BIO_push(buf,ssl)) == NULL) goto err; return(ret); err: if (buf != NULL) BIO_free(buf); if (ssl != NULL) BIO_free(ssl); #endif return(NULL); }
static int openssl_ssl_ctx_new_bio(lua_State*L) { SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); const char* host_addr = luaL_checkstring(L, 2); int server = lua_isnoneornil(L, 3) ? 0 : auxiliar_checkboolean(L, 3); int autoretry = lua_isnoneornil(L, 4) ? 1 : auxiliar_checkboolean(L, 4); SSL *ssl = NULL; BIO *bio = server ? BIO_new_ssl(ctx, 0) : BIO_new_ssl_connect(ctx); int ret = BIO_get_ssl(bio, &ssl); if (ret == 1 && ssl) { if (autoretry) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); if (server) { BIO* acpt = BIO_new_accept((char*)host_addr); BIO_set_accept_bios(acpt, bio); bio = acpt; } else { ret = BIO_set_conn_hostname(bio, host_addr); } 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 return openssl_pushresult(L, ret); } else { BIO_free(bio); bio = NULL; return 0; } }
bool tls_socket::set_hostname(const char* sAddr) { if(ctx == nullptr) { init_ctx(); if(ctx == nullptr) { print_error(); return false; } } if((bio = BIO_new_ssl_connect(ctx)) == nullptr) { print_error(); return false; } if(BIO_set_conn_hostname(bio, sAddr) != 1) { print_error(); return false; } BIO_get_ssl(bio, &ssl); if(ssl == nullptr) { print_error(); return false; } if(jconf::inst()->TlsSecureAlgos()) { if(SSL_set_cipher_list(ssl, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4:!SHA1") != 1) { print_error(); return false; } } return true; }
// ---------------------------------------------------------------------------- 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; }
bool ClientSSLSocket::Connect(std::string hostAndPort) { SSL_library_init(); _ctx.Reset(SSL_CTX_new(SSLv23_client_method())); if (!_ctx.Get()) { ERR_print_errors_fp(stderr); return false; } _bio.Reset(BIO_new_ssl_connect(_ctx.Get())); SSL* ssl = nullptr; // Set some flags. BIO_get_ssl(_bio.Get(), &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); // Create and setup the connection. BIO_set_conn_hostname(_bio.Get(), hostAndPort.c_str()); if (BIO_do_connect(_bio.Get()) <= 0) { std::cerr << "ERROR: Could not connect to \"" << hostAndPort << "\"" << std::endl; ERR_print_errors_fp(stderr); return false; } #if 0 // We don't care about the certificate validity at the moment. // Check the certificate. if (SSL_get_verify_result(ssl) != X509_V_OK) { std::cerr << "ERROR: Certificate verification error (" << SSL_get_verify_result(ssl) << ")" << std::endl; ERR_print_errors_fp(stderr); return false; } #endif // 0 return true; }
//BIO *BIO_new_ssl_connect(SSL_CTX *ctx); value _BIO_new_ssl_connect(value ctx) { return alloc_abstract(k_ssl_ctx_pointer, BIO_new_ssl_connect( (SSL_CTX*) val_data(ctx))); }
int anetSSLGenericConnect( char* err, char* addr, int port, int flags, anetSSLConnection* sslctn, char* certFilePath, char* certDirPath, char* checkCommonName ) { sslctn->sd = -1; sslctn->ctx = NULL; sslctn->ssl = NULL; sslctn->bio = NULL; sslctn->conn_str = NULL; // Set up a SSL_CTX object, which will tell our BIO object how to do its work SSL_CTX* ctx = SSL_CTX_new(TLSv1_1_client_method()); sslctn->ctx = ctx; // Create a SSL object pointer, which our BIO object will provide. SSL* ssl; // Create our BIO object for SSL connections. BIO* bio = BIO_new_ssl_connect(ctx); sslctn->bio = bio; // Failure? if (bio == NULL) { char errorbuf[1024]; ERR_error_string(1024,errorbuf); anetSetError(err, "SSL Error: Error creating BIO: %s\n", errorbuf); // We need to free up the SSL_CTX before we leave. anetCleanupSSL( sslctn ); return ANET_ERR; } // Makes ssl point to bio's SSL object. BIO_get_ssl(bio, &ssl); sslctn->ssl = ssl; // Set the SSL to automatically retry on failure. SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); char* connect_str = (char *)calloc( 1, strlen( addr ) + 10 ); sprintf( connect_str, "%s:%d", addr, port ); sslctn->conn_str = connect_str; // We're connection to to the redis server at IP:port. BIO_set_conn_hostname(bio, connect_str); SSL_CTX_load_verify_locations(ctx, certFilePath, certDirPath); // Same as before, try to connect. if (BIO_do_connect(bio) <= 0) { char errorbuf[1024]; ERR_error_string(1024,errorbuf); anetSetError(err, "SSL Error: Failed to connect: %s\n", errorbuf); anetCleanupSSL( sslctn ); return ANET_ERR; } // Now we need to do the SSL handshake, so we can communicate. if (BIO_do_handshake(bio) <= 0) { char errorbuf[1024]; ERR_error_string(1024,errorbuf); anetSetError(err, "SSL Error: handshake failure: %s\n", errorbuf); anetCleanupSSL( sslctn ); return ANET_ERR; } long verify_result = SSL_get_verify_result(ssl); if( verify_result == X509_V_OK) { X509* peerCertificate = SSL_get_peer_certificate(ssl); char commonName [512]; X509_NAME * name = X509_get_subject_name(peerCertificate); X509_NAME_get_text_by_NID(name, NID_commonName, commonName, 512); if( checkCommonName != NULL && strlen( checkCommonName ) > 0 ) { if(wildcmp(commonName, checkCommonName, strlen(checkCommonName)) == 0) { anetSetError(err, "SSL Error: Error validating peer common name: %s\n", commonName); anetCleanupSSL( sslctn ); return ANET_ERR; } } } else { char errorbuf[1024]; ERR_error_string(1024,errorbuf); anetSetError(err, "SSL Error: Error retrieving peer certificate: %s\n", errorbuf); anetCleanupSSL( sslctn ); return ANET_ERR; } int s = BIO_get_fd( bio, NULL ); if (flags & ANET_CONNECT_NONBLOCK) { if (anetNonBlock(err,s) != ANET_OK) return ANET_ERR; } return s; }
/** 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) { BIO *sbio = NULL, *out = NULL; int i, len, rv; char tmpbuf[1024]; SSL_CTX *ctx = NULL; SSL_CONF_CTX *cctx = NULL; SSL *ssl = NULL; CONF *conf = NULL; STACK_OF(CONF_VALUE) *sect = NULL; CONF_VALUE *cnf; const char *connect_str = "localhost:4433"; long errline = -1; ERR_load_crypto_strings(); ERR_load_SSL_strings(); SSL_library_init(); conf = NCONF_new(NULL); if (NCONF_load(conf, "connect.cnf", &errline) <= 0) { if (errline <= 0) fprintf(stderr, "Error processing config file\n"); else fprintf(stderr, "Error on line %ld\n", errline); goto end; } sect = NCONF_get_section(conf, "default"); if (sect == NULL) { fprintf(stderr, "Error retrieving default section\n"); goto end; } ctx = SSL_CTX_new(SSLv3_client_method()); cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { cnf = sk_CONF_VALUE_value(sect, i); rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); if (rv > 0) continue; if (rv != -2) { fprintf(stderr, "Error processing %s = %s\n", cnf->name, cnf->value); ERR_print_errors_fp(stderr); goto end; } if (!strcmp(cnf->name, "Connect")) { connect_str = cnf->value; } else { fprintf(stderr, "Unknown configuration option %s\n", cnf->name); goto end; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } /* * We'd normally set some stuff like the verify paths and * mode here * because as things stand this will connect to * any server whose * certificate is signed by any CA. */ sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if (!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); goto end; } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* We might want to do other things with ssl here */ BIO_set_conn_hostname(sbio, connect_str); out = BIO_new_fp(stdout, BIO_NOCLOSE); if (BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); goto end; } if (BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error establishing SSL connection\n"); ERR_print_errors_fp(stderr); goto end; } /* Could examine ssl here to get connection info */ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); for (;;) { len = BIO_read(sbio, tmpbuf, 1024); if (len <= 0) break; BIO_write(out, tmpbuf, len); } end: SSL_CONF_CTX_free(cctx); BIO_free_all(sbio); BIO_free(out); NCONF_free(conf); return 0; }
int main(int argc, char *argv[]) { BIO *sbio; SSL_CTX *ssl_ctx; SSL *ssl; X509 *server_cert; // Initialize OpenSSL OpenSSL_add_all_algorithms(); SSL_library_init(); SSL_load_error_strings(); // Check OpenSSL PRNG if(RAND_status() != 1) { fprintf(stderr, "OpenSSL PRNG not seeded with enough data."); goto error_1; } ssl_ctx = SSL_CTX_new(TLSv1_client_method()); // Enable certificate validation SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); // Configure the CA trust store to be used if (SSL_CTX_load_verify_locations(ssl_ctx, TRUSTED_CA_PATHNAME, NULL) != 1) { fprintf(stderr, "Couldn't load certificate trust store.\n"); goto error_2; } // Only support secure cipher suites if (SSL_CTX_set_cipher_list(ssl_ctx, SECURE_CIPHER_LIST) != 1) goto error_2; // Create the SSL connection sbio = BIO_new_ssl_connect(ssl_ctx); BIO_get_ssl(sbio, &ssl); if(!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); goto error_3; } // Do the SSL handshake BIO_set_conn_hostname(sbio, TARGET_SERVER); if(SSL_do_handshake(ssl) <= 0) { // SSL Handshake failed long verify_err = SSL_get_verify_result(ssl); if (verify_err != X509_V_OK) { // It failed because the certificate chain validation failed fprintf(stderr, "Certificate chain validation failed: %s\n", X509_verify_cert_error_string(verify_err)); } else { // It failed for another reason ERR_print_errors_fp(stderr); } goto error_3; } // Recover the server's certificate server_cert = SSL_get_peer_certificate(ssl); if (server_cert == NULL) { // The handshake was successful although the server did not provide a certificate // Most likely using an insecure anonymous cipher suite... get out! goto error_4; } // Validate the hostname if (validate_hostname(TARGET_HOST, server_cert) != MatchFound) { fprintf(stderr, "Hostname validation failed.\n"); goto error_5; } // Hostname validation succeeded; we can start sending data send_http_get_and_print(sbio); error_5: X509_free(server_cert); error_4: BIO_ssl_shutdown(sbio); error_3: BIO_free_all(sbio); error_2: SSL_CTX_free(ssl_ctx); error_1: // OpenSSL cleanup EVP_cleanup(); ERR_free_strings(); return 0; }
int test_ssl_certificate() { init_openssl(); SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method()); SSL * ssl; if (NULL == ctx) { DEBUG_PRINT("%s\n", "Failed to init SSL_CTX"); exit(1); } if(!SSL_CTX_load_verify_locations(ctx, NULL ,"/etc/ssl/certs")) { DEBUG_PRINT("%s\n", "Failed to load certs from /etc/ssl/certs"); exit(1); } BIO *bio; // Create secure BIO object bio = BIO_new_ssl_connect(ctx); if (NULL == bio) { DEBUG_PRINT("%s\n", "Failed to create the BIO object"); exit(1); } // Get the SSL connection from bio struct to ssl BIO_get_ssl(bio, &ssl); // Set SSL_MODE_AUTO_RETRY flag to allow retrying ssl handshake // int the background SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); DEBUG_PRINT("%s\n", "Performing SSL handshake with the host www.verisign.com"); // Set up connection hostname and port BIO_set_conn_hostname(bio, "www.verisign.com:https"); // Verify the connection opened and perform the handshake if (BIO_do_connect(bio) <= 0) { // Connection failed DEBUG_PRINT("%s\n", "Failed to open connection to host"); ERR_print_errors_fp(stderr); BIO_free_all(bio); exit(1); } // Verify certificate if(SSL_get_verify_result(ssl) != X509_V_OK) { // Problem in certificate DEBUG_PRINT("%s\n", "Failed to verify host certificate"); } else { DEBUG_PRINT("%s\n", "Verified host certificate"); } // Clean context structure SSL_CTX_free(ctx); /* To reuse the connection, use this line */ /*BIO_reset(bio);*/ /* To free it from memory, use this line */ BIO_free_all(bio); return 0; }
void *netConnectHttpsThread(void *threadParam) /* use a thread to run socket back to user */ { /* child */ struct netConnectHttpsParams *params = threadParam; pthread_detach(params->thread); // this thread will never join back with it's progenitor int fd=0; char hostnameProto[256]; BIO *sbio; SSL_CTX *ctx; SSL *ssl; openSslInit(); ctx = SSL_CTX_new(SSLv23_client_method()); fd_set readfds; fd_set writefds; int err; struct timeval tv; /* TODO checking certificates char *certFile = NULL; char *certPath = NULL; if (certFile || certPath) { SSL_CTX_load_verify_locations(ctx,certFile,certPath); #if (OPENSSL_VERSION_NUMBER < 0x0090600fL) SSL_CTX_set_verify_depth(ctx,1); #endif } // verify paths and mode. */ sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if(!ssl) { xerr("Can't locate SSL pointer"); goto cleanup; } /* Don't want any retries since we are non-blocking bio now */ //SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); safef(hostnameProto,sizeof(hostnameProto),"%s:%d",params->hostName,params->port); BIO_set_conn_hostname(sbio, hostnameProto); BIO_set_nbio(sbio, 1); /* non-blocking mode */ while (1) { if (BIO_do_connect(sbio) == 1) { break; /* Connected */ } if (! BIO_should_retry(sbio)) { xerr("BIO_do_connect() failed"); char s[256]; safef(s, sizeof s, "SSL error: %s", ERR_reason_error_string(ERR_get_error())); xerr(s); goto cleanup; } fd = BIO_get_fd(sbio, NULL); if (fd == -1) { xerr("unable to get BIO descriptor"); goto cleanup; } FD_ZERO(&readfds); FD_ZERO(&writefds); if (BIO_should_read(sbio)) { FD_SET(fd, &readfds); } else if (BIO_should_write(sbio)) { FD_SET(fd, &writefds); } else { /* BIO_should_io_special() */ FD_SET(fd, &readfds); FD_SET(fd, &writefds); } tv.tv_sec = 10; // timeout tv.tv_usec = 0; err = select(fd + 1, &readfds, &writefds, NULL, &tv); if (err < 0) { xerr("select() error"); goto cleanup; } if (err == 0) { char s[256]; safef(s, sizeof s, "connection timeout to %s", params->hostName); xerr(s); goto cleanup; } } /* TODO checking certificates if (certFile || certPath) if (!check_cert(ssl, host)) return -1; */ /* we need to wait on both the user's socket and the BIO SSL socket * to see if we need to ferry data from one to the other */ char sbuf[32768]; // socket buffer sv[1] to user char bbuf[32768]; // bio buffer int srd = 0; int swt = 0; int brd = 0; int bwt = 0; while (1) { // Do NOT move this outside the while loop. /* Get underlying file descriptor, needed for select call */ fd = BIO_get_fd(sbio, NULL); if (fd == -1) { xerr("BIO doesn't seem to be initialized in https, unable to get descriptor."); goto cleanup; } FD_ZERO(&readfds); FD_ZERO(&writefds); if (brd == 0) FD_SET(fd, &readfds); if (swt < srd) FD_SET(fd, &writefds); if (srd == 0) FD_SET(params->sv[1], &readfds); tv.tv_sec = 10; // timeout tv.tv_usec = 0; err = select(max(fd,params->sv[1]) + 1, &readfds, &writefds, NULL, &tv); /* Evaluate select() return code */ if (err < 0) { xerr("error during select()"); goto cleanup; } else if (err == 0) { /* Timed out - just quit */ xerr("https timeout expired"); goto cleanup; } else { if (FD_ISSET(params->sv[1], &readfds)) { swt = 0; srd = read(params->sv[1], sbuf, 32768); if (srd == -1) { if (errno != 104) // udcCache often closes causing "Connection reset by peer" xerrno("error reading https socket"); goto cleanup; } if (srd == 0) break; // user closed socket, we are done } if (FD_ISSET(fd, &writefds)) { int swtx = BIO_write(sbio, sbuf+swt, srd-swt); if (swtx <= 0) { if (!BIO_should_write(sbio)) { ERR_print_errors_fp(stderr); xerr("Error writing SSL connection"); goto cleanup; } } else { swt += swtx; if (swt >= srd) { swt = 0; srd = 0; } } } if (FD_ISSET(fd, &readfds)) { bwt = 0; brd = BIO_read(sbio, bbuf, 32768); if (brd <= 0) { if (BIO_should_read(sbio)) { brd = 0; continue; } else { if (brd == 0) break; ERR_print_errors_fp(stderr); xerr("Error reading SSL connection"); goto cleanup; } } // write the https data received immediately back on socket to user, and it's ok if it blocks. while(bwt < brd) { int bwtx = write(params->sv[1], bbuf+bwt, brd-bwt); if (bwtx == -1) { if ((errno != 104) // udcCache often closes causing "Connection reset by peer" && (errno != 32)) // udcCache often closes causing "Broken pipe" xerrno("error writing https data back to user socket"); goto cleanup; } bwt += bwtx; } brd = 0; bwt = 0; } } } cleanup: BIO_free_all(sbio); close(params->sv[1]); /* we are done with it */ return NULL; }
/** * 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)); }
Status getTLSCertificate(std::string hostname, QueryData& results) { SSL_library_init(); const auto method = TLSv1_method(); if (method == nullptr) { return Status(1, "Failed to create OpenSSL method object"); } auto delCTX = [](SSL_CTX* ctx) { SSL_CTX_free(ctx); }; auto ctx = std::unique_ptr<SSL_CTX, decltype(delCTX)>(SSL_CTX_new(method), delCTX); if (ctx == nullptr) { return Status(1, "Failed to create OpenSSL CTX object"); } auto delBIO = [](BIO* bio) { BIO_free_all(bio); }; auto server = std::unique_ptr<BIO, decltype(delBIO)>( BIO_new_ssl_connect(ctx.get()), delBIO); if (server == nullptr) { return Status(1, "Failed to create OpenSSL BIO object"); } std::string port = ":443"; auto ext_hostname = hostname; auto conn_hostname = hostname; auto delim = hostname.find(":"); if (delim == std::string::npos) { conn_hostname += ":443"; } else { ext_hostname = hostname.substr(0, delim); } auto ret = BIO_set_conn_hostname(server.get(), conn_hostname.c_str()); if (ret != 1) { return Status(1, "Failed to set OpenSSL hostname: " + std::to_string(ret)); } SSL* ssl = nullptr; BIO_get_ssl(server.get(), &ssl); if (ssl == nullptr) { return Status(1, "Failed to retrieve OpenSSL object"); } ret = SSL_set_tlsext_host_name(ssl, ext_hostname.c_str()); if (ret != 1) { return Status(1, "Failed to set OpenSSL server name: " + std::to_string(ret)); } ret = BIO_do_connect(server.get()); if (ret != 1) { return Status(1, "Failed to establish TLS connection: " + std::to_string(ret)); } ret = BIO_do_handshake(server.get()); if (ret != 1) { return Status(1, "Failed to complete TLS handshake: " + std::to_string(ret)); } auto delX509 = [](X509* cert) { X509_free(cert); }; auto cert = std::unique_ptr<X509, decltype(delX509)>( SSL_get_peer_certificate(ssl), delX509); if (cert == nullptr) { return Status(1, "No certificate"); } Row r; r["hostname"] = hostname; fillRow(r, cert.get()); results.push_back(r); return Status(); }
int main(int argc, char *argv[]) { if (argc < 4) { printf("UNSUPPORTED"); //for now at least return 3; } BIO *sbio; SSL_CTX *ssl_ctx; SSL *ssl; X509 *cert; int returncode = 0; char url[256]; sprintf(url, "%s:%s", argv[1], argv[2]); char ca_bundle[256]; strcpy(ca_bundle, argv[3]); //init: SSL_library_init(); SSL_load_error_strings(); ssl_ctx = SSL_CTX_new(TLSv1_client_method()); SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); if (SSL_CTX_load_verify_locations(ssl_ctx, ca_bundle, NULL) != 1) { printf("Couldn't load certificate trust store."); returncode=1; goto end; } else { goto connect; } connect: sbio = BIO_new_ssl_connect(ssl_ctx); BIO_get_ssl(sbio, &ssl); if (!ssl) { printf("Connection failed"); returncode=2; goto connect_end; } SSL_set_tlsext_host_name(ssl, url); BIO_set_conn_hostname(sbio, url); if(SSL_do_handshake(ssl) <= 0 || !verify_cert_hostname(SSL_get_peer_certificate(ssl), argv[1])) { printf ("VERIFY FAILURE"); } else { printf ("VERIFY SUCCESS"); } X509_free(cert); BIO_ssl_shutdown(sbio); connect_end: BIO_free_all(sbio); end: SSL_CTX_free(ssl_ctx); EVP_cleanup(); ERR_free_strings(); return returncode; }
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; }
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; }
int main(int argc, char *argv[]) { unsigned int bundleLength=0, urlLength=0; if (argc == 3) { printf("UNSUPPORTED\n"); //for now at least return EXIT_SUCCESS; } else if (argc != 4) { printf("usage: %s <host> <port> <ca-bundle>\n", argv[0]); return EXIT_FAILURE; } else if ((urlLength = strlen(argv[1]) + strlen(argv[2]) + 2) > MAX_LENGTH) { printf("Too long URL: %d characters, max: %d\n", urlLength, MAX_LENGTH); return EXIT_FAILURE; } else if ((bundleLength = strlen(argv[3]) + 1) > MAX_LENGTH) { printf("Too long ca-bundle filepath: %d characters, max: %d\n", bundleLength, MAX_LENGTH); return EXIT_FAILURE; } char url[1024]; snprintf(url, sizeof(url), "%s:%s", argv[1], argv[2]); char ca_bundle[1024]; memcpy(ca_bundle, argv[3], bundleLength); int exitvalue = 0; BIO *sbio; SSL_CTX *ssl_ctx; SSL *ssl; X509 *cert; const char *servername = NULL; X509_VERIFY_PARAM *param = NULL; SSL_load_error_strings(); SSL_library_init(); ssl_ctx = SSL_CTX_new(TLS_method()); //if you are using an older version of openssl, you may need to change this into for example: TLSv1_2_client_method param = SSL_CTX_get0_param(ssl_ctx); //set certificate verify //https://wiki.openssl.org/index.php/Hostname_validation X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); X509_VERIFY_PARAM_set1_host(param, argv[1], 0); SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); if (SSL_CTX_load_verify_locations(ssl_ctx, ca_bundle, NULL) != 1) { printf("Couldn't load certificate trust store\n"); printf("%s\n", ERR_reason_error_string(ERR_get_error())); exitvalue=EXIT_FAILURE; goto end; } sbio = BIO_new_ssl_connect(ssl_ctx); BIO_get_ssl(sbio, &ssl); if (!ssl) { printf("Connection failed\n"); printf("%s\n", ERR_reason_error_string(ERR_get_error())); exitvalue=EXIT_FAILURE; goto connect_end; } //handshake SSL_set_tlsext_host_name(ssl, url); BIO_set_conn_hostname(sbio, url); if(SSL_do_handshake(ssl) <= 0) { unsigned long int error = ERR_get_error(); printf("%s\n", ERR_reason_error_string(error)); printf("REJECT\n"); } else { printf ("ACCEPT\n"); } connect_end: BIO_free_all(sbio); end: SSL_CTX_free(ssl_ctx); EVP_cleanup(); ERR_free_strings(); return exitvalue; }
int crashreport_send(char *fname) { char buf[1024]; char header[512], footer[512]; char delimiter[41]; int filesize; int n; FILE *fd; SSL_CTX *ctx_client; BIO *socket = NULL; filesize = getfilesize(fname); if (filesize < 0) return 0; for (n = 0; n < sizeof(delimiter); n++) delimiter[n] = getrandom8()%26 + 'a'; delimiter[sizeof(delimiter)-1] = '\0'; snprintf(header, sizeof(header), "--%s\r\n" "Content-Disposition: form-data; name=\"upload\"; filename=\"crash.txt\"\r\n" "Content-Type: text/plain\r\n" "\r\n", delimiter); snprintf(footer, sizeof(footer), "\r\n--%s--\r\n", delimiter); ctx_client = crashreport_init_ssl(); if (!ctx_client) { printf("ERROR: SSL initalization failure (I)\n"); return 0; } socket = BIO_new_ssl_connect(ctx_client); if (!socket) { printf("ERROR: SSL initalization failure (II)\n"); return 0; } BIO_set_conn_hostname(socket, CRASH_REPORT_HOST ":443"); if (BIO_do_connect(socket) != 1) { printf("ERROR: Could not connect to %s\n", CRASH_REPORT_HOST); return 0; } if (BIO_do_handshake(socket) != 1) { printf("ERROR: Could not connect to %s (SSL handshake failed)\n", CRASH_REPORT_HOST); return 0; } snprintf(buf, sizeof(buf), "POST /crash.php HTTP/1.1\r\n" "User-Agent: UnrealIRCd %s\r\n" "Host: %s\r\n" "Accept: */*\r\n" "Content-Length: %d\r\n" "Expect: 100-continue\r\n" "Content-Type: multipart/form-data; boundary=%s\r\n" "\r\n", VERSIONONLY, CRASH_REPORT_HOST, (int)(filesize+strlen(header)+strlen(footer)), delimiter); BIO_puts(socket, buf); memset(buf, 0, sizeof(buf)); n = BIO_read(socket, buf, 255); if ((n < 0) || strncmp(buf, "HTTP/1.1 100", 12)) { printf("Error transmitting bug report (stage II, n=%d)\n", n); return 0; } fd = fopen(fname, "rb"); if (!fd) return 0; BIO_puts(socket, header); while ((fgets(buf, sizeof(buf), fd))) { BIO_puts(socket, buf); } fclose(fd); BIO_puts(socket, footer); do { } while(BIO_should_retry(socket)); /* make sure we are really finished (you never know with SSL) */ BIO_free_all(socket); SSL_CTX_free(ctx_client); return 1; }
/** * oh_ssl_connect * @hostname: Name of target host. Format: * "hostname:port" or "IPaddress:port" * @ctx: pointer to SSL_CTX as returned by oh_ssl_ctx_init() * @timeout: maximum number of seconds to wait for a connection to * hostname, or zero to wait forever * * Create and open a new ssl conection to the specified host. * * Return value: pointer to BIO, or NULL for failure **/ BIO *oh_ssl_connect(char *hostname, SSL_CTX *ctx, long timeout) { BIO *bio; SSL *ssl; fd_set readfds; fd_set writefds; struct timeval tv; int fd; int err; if (hostname == NULL) { err("NULL hostname in oh_ssl_connect()"); return(NULL); } if (ctx == NULL) { err("NULL ctx in oh_ssl_connect()"); return(NULL); } if (timeout < 0) { err("inappropriate timeout in oh_ssl_connect()"); return(NULL); } /* Start with a new SSL BIO */ bio = BIO_new_ssl_connect(ctx); if (bio == NULL) { err("BIO_new_ssl_connect() failed"); return(NULL); } /* Set up connection parameters for this BIO */ BIO_set_conn_hostname(bio, hostname); BIO_set_nbio(bio, 1); /* Set underlying socket to * non-blocking mode */ /* Set up SSL session parameters */ BIO_get_ssl(bio, &ssl); if (ssl == NULL) { err("BIO_get_ssl() failed"); BIO_free_all(bio); return(NULL); } SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); /* Ready to open the connection. Note that this call will probably * take a while, so we need to retry it, watching for a timeout. */ while (1) { if (BIO_do_connect(bio) == 1) { break; /* Connection established */ } if (! BIO_should_retry(bio)) { /* Hard error? */ err("BIO_do_connect() failed"); err("SSL error: %s", ERR_reason_error_string(ERR_get_error())); BIO_free_all(bio); return(NULL); } /* Wait until there's a change in the socket's status or until * the timeout period. * * Get underlying file descriptor, needed for the select call. */ fd = BIO_get_fd(bio, NULL); if (fd == -1) { err("BIO isn't initialized in oh_ssl_connect()"); BIO_free_all(bio); return(NULL); } FD_ZERO(&readfds); FD_ZERO(&writefds); if (BIO_should_read(bio)) { FD_SET(fd, &readfds); } else if (BIO_should_write(bio)) { FD_SET(fd, &writefds); } else { /* This is BIO_should_io_special(). * Not sure what "special" needs to * wait for, but both read and write * seems to work without unnecessary * retries. */ FD_SET(fd, &readfds); FD_SET(fd, &writefds); } if (timeout) { tv.tv_sec = timeout; tv.tv_usec = 0; err = select(fd + 1, &readfds, &writefds, NULL, &tv); } else { /* No timeout */ err = select(fd + 1, &readfds, &writefds, NULL, NULL); } /* Evaluate select() return code */ if (err < 0) { err("error during select()"); BIO_free_all(bio); return(NULL); } if (err == 0) { err("connection timeout to %s", hostname); BIO_free_all(bio); return(NULL); /* Timeout */ } } /* TODO: Do I need to set the client or server mode here? I don't * think so. */ return(bio); }