Ejemplo n.º 1
1
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
/*-
 * doConnection - make a connection
 * Args:
 *              scon    = earlier ssl connection for session id, or NULL
 * Returns:
 *              SSL *   = the connection pointer.
 */
static SSL *doConnection(SSL *scon)
{
    BIO *conn;
    SSL *serverCon;
    int width, i;
    fd_set readfds;

    if ((conn = BIO_new(BIO_s_connect())) == NULL)
        return (NULL);

/*      BIO_set_conn_port(conn,port);*/
    BIO_set_conn_hostname(conn, host);

    if (scon == NULL)
        serverCon = SSL_new(tm_ctx);
    else {
        serverCon = scon;
        SSL_set_connect_state(serverCon);
    }

    SSL_set_bio(serverCon, conn, conn);

    /* ok, lets connect */
    for (;;) {
        i = SSL_connect(serverCon);
        if (BIO_sock_should_retry(i)) {
            BIO_printf(bio_err, "DELAY\n");

            i = SSL_get_fd(serverCon);
            width = i + 1;
            FD_ZERO(&readfds);
            openssl_fdset(i, &readfds);
            /*
             * Note: under VMS with SOCKETSHR the 2nd parameter is currently
             * of type (int *) whereas under other systems it is (void *) if
             * you don't have a cast it will choke the compiler: if you do
             * have a cast then you can either go for (int *) or (void *).
             */
            select(width, (void *)&readfds, NULL, NULL, NULL);
            continue;
        }
        break;
    }
    if (i <= 0) {
        BIO_printf(bio_err, "ERROR\n");
        if (verify_error != X509_V_OK)
            BIO_printf(bio_err, "verify error:%s\n",
                       X509_verify_cert_error_string(verify_error));
        else
            ERR_print_errors(bio_err);
        if (scon == NULL)
            SSL_free(serverCon);
        return NULL;
    }

    return serverCon;
}
Ejemplo n.º 6
0
/***********************************************************************
 * doConnection - make a connection
 * Args:
 *		scon	= earlier ssl connection for session id, or NULL
 * Returns:
 *		SSL *	= the connection pointer.
 */
static SSL *
doConnection(SSL * scon)
{
	BIO *conn;
	SSL *serverCon;
	int width, i;
	fd_set readfds;

	if ((conn = BIO_new(BIO_s_connect())) == NULL)
		return (NULL);

/*	BIO_set_conn_port(conn,port);*/
	BIO_set_conn_hostname(conn, host);

	if (scon == NULL)
		serverCon = SSL_new(tm_ctx);
	else {
		serverCon = scon;
		SSL_set_connect_state(serverCon);
	}

	SSL_set_bio(serverCon, conn, conn);

#if 0
	if (scon != NULL)
		SSL_set_session(serverCon, SSL_get_session(scon));
#endif

	/* ok, lets connect */
	for (;;) {
		i = SSL_connect(serverCon);
		if (BIO_sock_should_retry(i)) {
			BIO_printf(bio_err, "DELAY\n");

			i = SSL_get_fd(serverCon);
			width = i + 1;
			FD_ZERO(&readfds);
			FD_SET(i, &readfds);
			select(width, &readfds, NULL, NULL, NULL);
			continue;
		}
		break;
	}
	if (i <= 0) {
		BIO_printf(bio_err, "ERROR\n");
		if (verify_error != X509_V_OK)
			BIO_printf(bio_err, "verify error:%s\n",
			    X509_verify_cert_error_string(verify_error));
		else
			ERR_print_errors(bio_err);
		if (scon == NULL)
			SSL_free(serverCon);
		return NULL;
	}
	return serverCon;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
/***********************************************************************
 * doConnection - make a connection
 * Args:
 *		scon	= earlier ssl connection for session id, or NULL
 * Returns:
 *		SSL *	= the connection pointer.
 */
static SSL *
doConnection(SSL * scon)
{
	struct pollfd pfd[1];
	SSL *serverCon;
	BIO *conn;
	long verify_error;
	int i;

	if ((conn = BIO_new(BIO_s_connect())) == NULL)
		return (NULL);

/*	BIO_set_conn_port(conn,port);*/
	BIO_set_conn_hostname(conn, s_time_config.host);

	if (scon == NULL)
		serverCon = SSL_new(tm_ctx);
	else {
		serverCon = scon;
		SSL_set_connect_state(serverCon);
	}

	SSL_set_bio(serverCon, conn, conn);

	/* ok, lets connect */
	for (;;) {
		i = SSL_connect(serverCon);
		if (BIO_sock_should_retry(i)) {
			BIO_printf(bio_err, "DELAY\n");

			i = SSL_get_fd(serverCon);
			pfd[0].fd = i;
			pfd[0].events = POLLIN;
			poll(pfd, 1, -1);
			continue;
		}
		break;
	}
	if (i <= 0) {
		BIO_printf(bio_err, "ERROR\n");
		verify_error = SSL_get_verify_result(serverCon);
		if (verify_error != X509_V_OK)
			BIO_printf(bio_err, "verify error:%s\n",
			    X509_verify_cert_error_string(verify_error));
		else
			ERR_print_errors(bio_err);
		if (scon == NULL)
			SSL_free(serverCon);
		return NULL;
	}
	return serverCon;
}
Ejemplo n.º 10
0
BIO *BIO_new_connect(const char *hostname) {
  BIO *ret;

  ret = BIO_new(BIO_s_connect());
  if (ret == NULL) {
    return NULL;
  }
  if (!BIO_set_conn_hostname(ret, hostname)) {
    BIO_free(ret);
    return NULL;
  }
  return ret;
}
Ejemplo n.º 11
0
/*-
 * doConnection - make a connection
 */
static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx)
{
    BIO *conn;
    SSL *serverCon;
    int i;

    if ((conn = BIO_new(BIO_s_connect())) == NULL)
        return NULL;

    BIO_set_conn_hostname(conn, host);
    BIO_set_conn_mode(conn, BIO_SOCK_NODELAY);

    if (scon == NULL)
        serverCon = SSL_new(ctx);
    else {
        serverCon = scon;
        SSL_set_connect_state(serverCon);
    }

    SSL_set_bio(serverCon, conn, conn);

    /* ok, lets connect */
    i = SSL_connect(serverCon);
    if (i <= 0) {
        BIO_printf(bio_err, "ERROR\n");
        if (verify_args.error != X509_V_OK)
            BIO_printf(bio_err, "verify error:%s\n",
                       X509_verify_cert_error_string(verify_args.error));
        else
            ERR_print_errors(bio_err);
        if (scon == NULL)
            SSL_free(serverCon);
        return NULL;
    }

#if defined(SOL_SOCKET) && defined(SO_LINGER)
    {
        struct linger no_linger;
        int fd;

        no_linger.l_onoff  = 1;
        no_linger.l_linger = 0;
        fd = SSL_get_fd(serverCon);
        if (fd >= 0)
            (void)setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&no_linger,
                             sizeof(no_linger));
    }
#endif

    return serverCon;
}
Ejemplo n.º 12
0
BIO *BIO_new_connect(char *str)
	{
	BIO *ret;

	ret=BIO_new(BIO_s_connect());
	if (ret == NULL) return(NULL);
	if (BIO_set_conn_hostname(ret,str))
		return(ret);
	else
		{
		BIO_free(ret);
		return(NULL);
		}
	}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
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;
  }
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
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);
}
Ejemplo n.º 19
0
/*
  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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
{
	int status;
	UINT32 option_value;
	socklen_t option_len;

	if (!hostname)
		return FALSE;

	if (hostname[0] == '/')
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;

		tcp->socketBio = BIO_new_fd(tcp->sockfd, 1);

		if (!tcp->socketBio)
			return FALSE;
	}
	else
	{
		fd_set cfds;
		struct timeval tv;

		tcp->socketBio = BIO_new(BIO_s_connect());

		if (!tcp->socketBio)
			return FALSE;

		if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
			return FALSE;

		BIO_set_nbio(tcp->socketBio, 1);

		status = BIO_do_connect(tcp->socketBio);

		if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
			return FALSE;

		tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);

		if (tcp->sockfd < 0)
			return FALSE;

		if (status <= 0)
		{
			FD_ZERO(&cfds);
			FD_SET(tcp->sockfd, &cfds);

			tv.tv_sec = timeout;
			tv.tv_usec = 0;

			status = select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);

			if (status == 0)
			{
				return FALSE; /* timeout */
			}
		}

		BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
		BIO_free(tcp->socketBio);

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return -1;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}

	SetEventFileDescriptor(tcp->event, tcp->sockfd);

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);

	if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
		fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);

			if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
			{
				fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__);
				return FALSE;
			}
		}
	}

	if (!tcp_set_keep_alive_mode(tcp))
		return FALSE;

	tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());

	if (!tcp->bufferedBio)
		return FALSE;

	tcp->bufferedBio->ptr = tcp;

	tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);

	return TRUE;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
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 */
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
Archivo: run.c Proyecto: ouspg/trytls
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;
}
Ejemplo n.º 26
0
/**
 * 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));  
}
Ejemplo n.º 27
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;
}
Ejemplo n.º 28
0
/**
 * 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);
}
Ejemplo n.º 29
0
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;
}
Ejemplo n.º 30
0
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();
}