static enum pbpal_resolv_n_connect_result resolv_and_connect_wout_SSL(pubnub_t *pb)
{
    PUBNUB_LOG_TRACE("resolv_and_connect_wout_SSL\n");
    if (NULL == pb->pal.socket) {
        char const*origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN;
        PUBNUB_LOG_TRACE("pb=%p: Don't have BIO\n", pb);
        pb->pal.socket = BIO_new_connect((char*)origin);
    }
    if (NULL == pb->pal.socket) {
        return pbpal_resolv_resource_failure;
    }
    BIO_set_conn_port(pb->pal.socket, "http");

    BIO_set_nbio(pb->pal.socket, !pb->options.use_blocking_io);

    WATCH_ENUM(pb->options.use_blocking_io);
    if (BIO_do_connect(pb->pal.socket) <= 0) {
        if (BIO_should_retry(pb->pal.socket)) {
            return pbpal_connect_wouldblock;
        }
        ERR_print_errors_cb(print_to_pubnub_log, NULL);
        PUBNUB_LOG_ERROR("BIO_do_connect failed\n");
        return pbpal_connect_failed;
    }

    PUBNUB_LOG_TRACE("pb=%p: BIO connected\n", pb);
    {
        int fd = BIO_get_fd(pb->pal.socket, NULL);
        socket_set_rcv_timeout(fd, pb->transaction_timeout_ms);
    }

    return pbpal_connect_success;
}
Exemplo n.º 2
0
static int openssl_bio_new_connect(lua_State *L)
{
  const char *host = luaL_checkstring(L, 1);
  BIO* bio = BIO_new_connect((char*)host);
  int doconn = 1;

  if (lua_isstring(L, 2))
  {
    if (BIO_set_conn_port(bio, lua_tostring(L, 2)) <= 0)
    {
      BIO_free(bio);
      bio = NULL;
    }
    else
    {
      doconn = lua_isnoneornil(L, 3) ? doconn : auxiliar_checkboolean(L, 3);
    }
  }
  else
    doconn = auxiliar_checkboolean(L, 2);

  if (bio)
  {
    int ret = 1;
    if (doconn)
    {
      ret = BIO_do_connect(bio);
    }

    if (ret == 1)
    {
      PUSH_OBJECT(bio, "openssl.bio");
      openssl_newvalue(L, bio);

      lua_pushboolean(L, 1);
      openssl_setvalue(L, bio, "free_all");
      return 1;
    }
    else
    {
      BIO_free(bio);
      luaL_error(L, "Error creating connection to remote machine");
    }
  }

  if (!bio)
    luaL_error(L, "Error creating connection BIO");

  return 0;
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
int BIO_set_conn_int_port(BIO *bio, const int *port) {
  char buf[DECIMAL_SIZE(int) + 1];
  BIO_snprintf(buf, sizeof(buf), "%d", *port);
  return BIO_set_conn_port(bio, buf);
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
QByteArray SSLConnect::getUrl( RequestType type, const QString &value )
{
	if( !d->ssl )
		return QByteArray();

	if( !SSL_check_private_key( d->ssl ) )
	{
		d->setError();
		return QByteArray();
	}

	QString label;
	HTTPRequest req;
	switch( type )
	{
	case AccessCert:
	{
		label = tr("Loading server access certificate. Please wait.");
		SOAPDocument s( "GetAccessToken", "urn:GetAccessToken" );
		s.writeParameter( "Language", Settings::language().toUpper() );
		s.writeParameter( "RequestTime", "" );
		s.writeParameter( "SoftwareName", "DigiDoc3" );
		s.writeParameter( "SoftwareVersion", qApp->applicationVersion() );
		s.finalize();
		req = HTTPRequest( "POST", "1.1", "https://id.sk.ee/GetAccessTokenWS/" );
		req.setRawHeader( "Content-Type", "text/xml" );
		req.setRawHeader( "SOAPAction", QByteArray() );
		req.setRawHeader( "Connection", "close" );
		req.setContent( s.document() );
		break;
	}
	case MobileInfo:
	{
		label = tr("Loading Mobile info");
		SOAPDocument s( "GetMIDTokens", "urn:GetMIDTokens" );
		s.finalize();
		req = HTTPRequest( "POST", "1.1", "https://id.sk.ee/MIDInfoWS/" );
		req.setRawHeader( "Content-Type", "text/xml" );
		req.setRawHeader( "SOAPAction", QByteArray() );
		req.setRawHeader( "Connection", "close" );
		req.setContent( s.document() );
		break;
	}
	case EmailInfo:
		label = tr("Loading Email info");
		req = HTTPRequest( "GET", "1.0",
			"https://sisene.www.eesti.ee/idportaal/postisysteem.naita_suunamised" );
		break;
	case ActivateEmails:
		label = tr("Loading Email info");
		req = HTTPRequest( "GET", "1.0",
			QString("https://www.eesti.ee/portaal/!postisysteem.suunamised?%1").arg( value ) );
		break;
	case PictureInfo:
		label = tr("Downloading picture");
		req = HTTPRequest( "GET", "1.0",
			"https://sisene.www.eesti.ee/idportaal/portaal.idpilt" );
		break;
	default: return QByteArray();
	}

	QByteArray url = req.url().host().toUtf8();
	BIO *sock = BIO_new_connect( (char*)url.constData() );
	BIO_set_conn_port( sock, "https" );
	if( BIO_do_connect( sock ) <= 0 )
	{
		d->setError( tr( "Failed to connect to host. Are you connected to the internet?" ) );
		return QByteArray();
	}

	SSL_set_bio( d->ssl, sock, sock );
	if( !SSL_connect( d->ssl ) )
	{
		d->setError();
		return QByteArray();
	}

	QByteArray header = req.request();
	if( !SSL_write( d->ssl, header.constData(), header.size() ) )
	{
		d->setError();
		return QByteArray();
	}

	QProgressDialog p( label, QString(), 0, 0, qApp->activeWindow() );
	p.setWindowFlags( (p.windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowCloseButtonHint );
	if( QProgressBar *bar = p.findChild<QProgressBar*>() )
		bar->setTextVisible( false );
	p.open();

	return SSLReadThread( d ).waitForDone();
}
Exemplo n.º 8
0
/*
 * This function sends a OCSP request to a defined OCSP responder
 * and checks the OCSP response for correctness.
 */
static int ocsp_check(X509_STORE *store, X509 *issuer_cert, X509 *client_cert,
		      EAP_TLS_CONF *conf)
{
	OCSP_CERTID *certid;
	OCSP_REQUEST *req;
	OCSP_RESPONSE *resp;
	OCSP_BASICRESP *bresp = NULL;
	char *host = NULL;
	char *port = NULL;
	char *path = NULL;
	int use_ssl = -1;
	BIO *cbio;
	int ocsp_ok;
	int status;

	/* 
	 * Create OCSP Request 
	 */
	certid = OCSP_cert_to_id(NULL, client_cert, issuer_cert);
	req = OCSP_REQUEST_new();
	OCSP_request_add0_id(req, certid);
	OCSP_request_add1_nonce(req, NULL, 8);

	/* 
	 * Send OCSP Request and get OCSP Response
	 */

	/* Get OCSP responder URL */ 
	if(conf->ocsp_override_url) {
		OCSP_parse_url(conf->ocsp_url, &host, &port, &path, &use_ssl);
	}
	else {
		ocsp_parse_cert_url(client_cert, &host, &port, &path, &use_ssl);
	}
	
	DEBUG2("[ocsp] --> Responder URL = http://%s:%s%s", host, port, path);

	/* Setup BIO socket to OCSP responder */
	cbio = BIO_new_connect(host);
	BIO_set_conn_port(cbio, port);
	BIO_do_connect(cbio);

	/* Send OCSP request and wait for response */
	resp = OCSP_sendreq_bio(cbio, path, req);
	if(resp==0) {
		radlog(L_ERR, "Error: Couldn't get OCSP response");
		ocsp_ok = 0;
		goto ocsp_end;
	}

	/* Verify OCSP response */
	status = OCSP_response_status(resp);
	if(status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
		radlog(L_ERR, "Error: OCSP response status: %s", OCSP_response_status_str(status));
		ocsp_ok = 0;
		goto ocsp_end;
	}
	bresp = OCSP_response_get1_basic(resp);
	if(OCSP_check_nonce(req, bresp)!=1) {
		radlog(L_ERR, "Error: OCSP response has wrong nonce value");
		ocsp_ok = 0;
		goto ocsp_end;
	}
	if(OCSP_basic_verify(bresp, NULL, store, 0)!=1){
		radlog(L_ERR, "Error: Couldn't verify OCSP basic response");
		ocsp_ok = 0;
		goto ocsp_end;
	}
	
	ocsp_ok = 1; 

ocsp_end:
	/* Free OCSP Stuff */
	OCSP_REQUEST_free(req);
	OCSP_RESPONSE_free(resp);
	free(host);
	free(port);
	free(path);
	BIO_free_all(cbio);
	OCSP_BASICRESP_free(bresp);

	if (ocsp_ok) {
		DEBUG2("[ocsp] --> Certificate is valid!");
	} else {
		DEBUG2("[ocsp] --> Certificate has been expired/revoked!");
	}

	return ocsp_ok;
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
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, int time_is_an_illusion)
{
  BIO *s_bio;
  SSL_CTX *ctx;
  SSL *ssl;

  SSL_load_error_strings();
  SSL_library_init();

  ctx = NULL;
  if (0 == strcmp("sslv23", protocol))
  {
    verb ("V: using SSLv23_client_method()\n");
    ctx = SSL_CTX_new(SSLv23_client_method());
  } else if (0 == strcmp("sslv3", protocol))
  {
    verb ("V: using SSLv3_client_method()\n");
    ctx = SSL_CTX_new(SSLv3_client_method());
  } else if (0 == strcmp("tlsv1", protocol))
  {
    verb ("V: using TLSv1_client_method()\n");
    ctx = SSL_CTX_new(TLSv1_client_method());
  } else
    die("Unsupported protocol `%s'\n", protocol);

  if (ctx == NULL)
    die("OpenSSL failed to support protocol `%s'\n", protocol);

  if (ca_racket)
  {
    if (1 != SSL_CTX_load_verify_locations(ctx, NULL, certdir))
      fprintf(stderr, "SSL_CTX_load_verify_locations failed\n");
  }

  if (NULL == (s_bio = BIO_new_ssl_connect(ctx)))
    die ("SSL BIO setup failed\n");
  BIO_get_ssl(s_bio, &ssl);
  if (NULL == ssl)
    die ("SSL setup failed\n");

  if (time_is_an_illusion)
  {
    SSL_set_info_callback(ssl, openssl_time_callback);
  }

  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
  if ( (1 != BIO_set_conn_hostname(s_bio, host)) ||
       (1 != BIO_set_conn_port(s_bio, port)) )
    die ("Failed to initialize connection to `%s:%s'\n", host, port);

  if (NULL == BIO_new_fp(stdout, BIO_NOCLOSE))
    die ("BIO_new_fp returned error, possibly: %s", strerror(errno));

  // This should run in seccomp
  // eg:     prctl(PR_SET_SECCOMP, 1);
  if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later?
    die ("SSL connection failed\n");
  if (1 != BIO_do_handshake(s_bio))
    die ("SSL handshake failed\n");

  // Verify the peer certificate against the CA certs on the local system
  if (ca_racket) {
    inspect_key (ssl, host);
  } else {
    verb ("V: Certificate verification skipped!\n");
  }
  check_key_length(ssl);
  // from /usr/include/openssl/ssl3.h
  //  ssl->s3->server_random is an unsigned char of 32 bits
  memcpy(time_map, ssl->s3->server_random, sizeof (uint32_t));
  SSL_free(ssl);
  SSL_CTX_free(ctx);
}
Exemplo n.º 11
0
BIO *
httpsGetFileDesc(char * hostname, int port, char * remotename,
	char *extraHeaders, int *errorcode, char **returnedHeaders) 
{
	char *buf;
	char headers[4096];
	char *nextChar = headers;
	char *hstr;
	int sock;
	int rc;
	int checkedCode;
	int headerslen;

	int bufsize;
	int byteswritten;
	struct loaderData_s * loaderData;
	SSL_CTX *ssl_context;
	SSL *ssl;
	BIO *sbio = 0;
	X509 *server_cert;

	*errorcode = 0;

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (sock < 0) {
		logMessage(ERROR,
			"ROCKS:httpsGetFileDesc:Could not get a socket");
		*errorcode = FTPERR_FAILED_CONNECT;
		return NULL;
	}

	/* OpenSSL_add_all_algorithms(); */
	SSLeay_add_ssl_algorithms();

	ssl_context = SSL_CTX_new(SSLv23_client_method());
	if (!ssl_context) {
		logMessage(ERROR, "Could not create SSLv2,3 context");
		*errorcode = FTPERR_FAILED_CONNECT;
		goto error;
	}

	/* Pull in the Global Loader Data structure. */
	loaderData = rocks_global_loaderData;

	/* I have a Certificate */
	if (loaderData->cert_filename) {
		rc = SSL_CTX_use_certificate_file(ssl_context, 
			loaderData->cert_filename,
			SSL_FILETYPE_PEM);
		if (!rc) {
			logMessage(ERROR, "Could not read Cluster Certificate");
			*errorcode = FTPERR_CLIENT_SECURITY;
			goto error;
		}

		rc = SSL_CTX_use_PrivateKey_file(ssl_context, 
			loaderData->priv_filename,
			SSL_FILETYPE_PEM);
		if (!rc) {
			logMessage(ERROR,
				"Could not read Cluster cert private key");
			*errorcode = FTPERR_CLIENT_SECURITY;
			goto error;
		}

		/* Only connect to servers that have certs signed by
		 * our trusted CA. */
		if (loaderData->authParent) {
			rc = SSL_CTX_load_verify_locations(ssl_context,
				loaderData->ca_filename, 0);
			if (!rc) {
				logMessage(ERROR,
					"Could not read Server CA cert");
				*errorcode = FTPERR_CLIENT_SECURITY;
				goto error;
			}
			SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, 0);
			SSL_CTX_set_verify_depth(ssl_context, 1);
		}
	}

	sbio = BIO_new_ssl_connect(ssl_context);
	if (!sbio) {
		logMessage(ERROR, "Could not create SSL object");
		*errorcode = FTPERR_CLIENT_SECURITY;
		goto error;
	}

	BIO_get_ssl(sbio, &ssl);
	if (!ssl) {
		logMessage(ERROR, "Could not find ssl pointer.");
		*errorcode = FTPERR_CLIENT_SECURITY;
		goto error;
	}

	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

	BIO_set_conn_hostname(sbio, hostname);
	BIO_set_conn_port(sbio, "https");

	rc = BIO_do_connect(sbio);
	if (rc<=0) {
		rc = SSL_get_verify_result(ssl);
		if (rc) {
			logMessage(ERROR, "Could not verify %s's identity",
				hostname);	
			*errorcode = FTPERR_REFUSED;
			goto error;
		}
		logMessage(ERROR, "Could not connect to %s:https", hostname);
		*errorcode = FTPERR_FAILED_CONNECT;
		goto error;
	}

	rc = BIO_do_handshake(sbio);
	if (rc<=0) {
		logMessage(ERROR,
			"Could not establish HTTPS connection with %s", 
			hostname);
		*errorcode = FTPERR_FAILED_CONNECT;
		goto error;
	}

	server_cert = SSL_get_peer_certificate(ssl);

	/* Show credentials if appropriate. */
	/* Don't Show Credentials */
	if ( (0 == 1)  && !loaderData->cert_filename 
			&& !loaderData->ekv
			&& !loaderData->dropCert) {

		rc = show_cert(server_cert);
		if (rc != 1) {
			*errorcode = FTPERR_REFUSED;
			goto error;
		}
	}

	if (extraHeaders)
		hstr = extraHeaders;
	else
		hstr = "";

	bufsize = strlen(remotename) + strlen(hostname) + strlen(hstr) + 30;

	if ((buf = malloc(bufsize)) == NULL) {
			logMessage(ERROR,
				"ROCKS:httpsGetFileDesc:malloc failed");
			*errorcode = FTPERR_FAILED_CONNECT;
			goto error;
	}

	sprintf(buf, "GET %s HTTP/1.0\r\nHost: %s\r\n%s\r\n", remotename, 
		hostname, hstr);

	byteswritten = BIO_puts(sbio, buf);

	logMessage(INFO,
		"ROCKS:httpsGetFileDesc:byteswritten(%d)", byteswritten);
	logMessage(INFO,
		"ROCKS:httpsGetFileDesc:bufsize(%d)", (int)strlen(buf));

	free(buf);

	/* This is fun; read the response a character at a time until we:
	1) Get our first \r\n; which lets us check the return code
	2) Get a \r\n\r\n, which means we're done */

	*nextChar = '\0';
	checkedCode = 0;
	headerslen = 0;
	while (!strstr(headers, "\r\n\r\n")) {

		if (BIO_read(sbio, nextChar, 1) != 1) {
			*errorcode = FTPERR_SERVER_SECURITY;
			goto error;
		}

		nextChar++;
		*nextChar = '\0';
		++headerslen;

		if (nextChar - headers == sizeof(headers)) {
			goto error;
		}

		if (!checkedCode && strstr(headers, "\r\n")) {
			char * start, * end;

			checkedCode = 1;
			start = headers;
			while (!isspace(*start) && *start) start++;
			if (!*start) {
				goto error;
			}

			while (isspace(*start) && *start) start++;

			end = start;
			while (!isspace(*end) && *end) end++;
			if (!*end) {
				goto error;
			}

			logMessage(INFO,
				"ROCKS:httpsGetFileDesc:status %s.", start);

			*end = '\0';
			if (!strcmp(start, "404"))
				goto error;
			else if (!strcmp(start, "403")) {
				*errorcode = FTPERR_SERVER_SECURITY;
				goto error;
			}
			else if (!strcmp(start, "503")) {
				/* A server nack - busy */
				logMessage(WARNING, "ROCKS:server busy");
				watchdog_reset();
				*errorcode = FTPERR_FAILED_DATA_CONNECT;
				goto error;
			}
			else if (strcmp(start, "200")) {
				*errorcode = FTPERR_BAD_SERVER_RESPONSE;
				goto error;
			}

			*end = ' ';
		}
	}

	if ((*returnedHeaders = (char *)malloc(headerslen + 1)) != NULL) {
		memcpy(*returnedHeaders, headers, headerslen + 1);
	}

	return sbio;

error:
	close(sock);
	if (sbio)
		BIO_free_all(sbio);
	if (!*errorcode)
		*errorcode = FTPERR_SERVER_IO_ERROR;
	logMessage(ERROR, "ROCKS:httpsGetFileDesc:Error %s", 
		ftpStrerror(*errorcode, URL_METHOD_HTTP));
	return NULL;
}
Exemplo n.º 12
0
int main(int argc, char **argv) {
   BIO *bio;
   SSL *ssl;
   SSL_ERR err;
   char c;
   char *host = "google.com";
   char *port = "443";

   char *sendtemplate = "HEAD / HTTP/1.1\r\nHost: %s\r\n\r\n";
   char sendbuf[BUFFSZ];
   char recvbuf[BUFFSZ];
   int nbytes;

   SSL_library_init();
   SSL_load_error_strings();
   ERR_load_BIO_strings();
   OpenSSL_add_all_algorithms();

   SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());

   while((c = getopt(argc, argv, "h:p:")) != -1) {
      switch(c) {
      case 'h':
         host = optarg;
         break;
      case 'p':
         port = optarg;
         break;
      case '?':
         return 1;
         break;
      }
   }

   snprintf(sendbuf, BUFFSZ, sendtemplate, host);

   if(!ctx) {
      err = ERR_get_error();
      printf("%s\n", ERR_error_string(err, NULL));
      return 1;
   }

   bio = BIO_new_ssl_connect(ctx);
   BIO_get_ssl(bio, &ssl);
   SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

   BIO_set_conn_hostname(bio, host);
   BIO_set_conn_port(bio, port);

   if(BIO_do_connect(bio) <= 0) {
      err = ERR_get_error();
      printf("%s\n", ERR_error_string(err, NULL));
      return 1;
   }

   /*
    * TODO flesh this out
    * send request, and print the response
    */
   BIO_write(bio, sendbuf, strlen(sendbuf));
   nbytes = BIO_read(bio, recvbuf, sizeof(recvbuf));
   printf("%s\n", recvbuf);

   BIO_free_all(bio);
   return 0;
}
Exemplo n.º 13
0
int SSLBufferConnect(struct sslbuffer_t *sslbuffer, const char *host,
	const char *port)
{
	int res;
	int fd;
	struct event *ev_write = NULL;
	struct event *ev_read = NULL;
	BIO *bio = NULL;
	unsigned long error;

	bio = BIO_new(BIO_s_connect( ));
	if (bio == NULL)
		return 0;

	BIO_set_conn_hostname(bio, host);
	BIO_set_conn_port(bio, port);
	BIO_set_nbio(bio, 1);

	SSL_set_bio(sslbuffer->ssl, bio, bio);

	res = SSL_connect(sslbuffer->ssl);
	if (res <= 0)
	{
		error = SSL_get_error(sslbuffer->ssl, res);
		sslbuffer->fl_connecting = 1;
		if ( (error != SSL_ERROR_WANT_CONNECT) &&
		     (error != SSL_ERROR_WANT_READ) &&
		     (error != SSL_ERROR_WANT_WRITE) )
		{
			printf("%s:%d: unknown error %lu\n", __FILE__, __LINE__, error);
			print_errors();
			goto Error;
		}
	}

	fd = BIO_get_fd(bio, NULL);

	ev_read = event_new(sslbuffer->base, fd, EV_READ|EV_PERSIST, SSLBuffer_func, sslbuffer);
	if (ev_read == NULL)
		goto Error;
	res = event_add(ev_read, NULL);
	if (res != 0)
		goto Error;
	sslbuffer->ev_read = ev_read;

	ev_write = event_new(sslbuffer->base, fd, EV_WRITE|EV_PERSIST, SSLBuffer_func, sslbuffer);
	if (ev_write == NULL)
		goto Error;

    res = event_add(ev_write, NULL);
    if (res != 0)
        goto Error;
	sslbuffer->ev_write = ev_write;

	return 1;

Error:
	if (ev_write != NULL)
		event_free(ev_write);
	if (ev_read != NULL)
		event_free(ev_read);
	return 0;
}
Exemplo n.º 14
0
int proxy_null(BIO **cbio, BIO **sbio, char *header)
{
   char data[READ_BUFF_SIZE];
   int len, written;
   char *host, *p;

   /* retrieve the host tag */
   host = strcasestr(header, HTTP_HOST_TAG);

   if (host == NULL)
      return -EINVALID;

   SAFE_STRDUP(host, host + strlen(HTTP_HOST_TAG));

   /* trim the eol */
   if ((p = strchr(host, '\r')) != NULL)
      *p = 0;
   if ((p = strchr(host, '\n')) != NULL)
      *p = 0;

   /* connect to the real server */
   *sbio = BIO_new(BIO_s_connect());
   BIO_set_conn_hostname(*sbio, host);
   BIO_set_conn_port(*sbio, "http");

   if (BIO_do_connect(*sbio) <= 0) {
      DEBUG_MSG(D_ERROR, "Cannot connect to [%s]", host);
      SAFE_FREE(host);
      return -ENOADDRESS;
   }

   DEBUG_MSG(D_INFO, "Connection to [%s]", host);

   /*
    * sanitize the header to avoid strange reply from the server.
    * we don't want to cope with keep-alive !!!
    */
   sanitize_header(header);

   /* send the request to the server */
   BIO_puts(*sbio, header);

   memset(data, 0, sizeof(data));
   written = 0;

   /* read the reply header from the server */
   LOOP {
      len = BIO_read(*sbio, data + written, sizeof(char));
      if (len <= 0)
         break;

      written += len;
      if (strstr(data, CR LF CR LF) || strstr(data, LF LF))
         break;
   }

   /* send the headers to the client, the data will be sent in the callee function */
   BIO_write(*cbio, data, written);

   SAFE_FREE(host);

   return ESUCCESS;
}
Exemplo n.º 15
0
//--------------------------------------------------
// sends an OCSP_REQUES object to remore server and
// retrieves the OCSP_RESPONSE object
// resp - buffer to store the new responses pointer
// req - request objects pointer
// url - OCSP responder URL
//--------------------------------------------------
int ddocPullUrl(const char* url, DigiDocMemBuf* pSendData, DigiDocMemBuf* pRecvData,
                const char* proxyHost, const char* proxyPort)
{
    BIO* cbio = 0, *sbio = 0;
    SSL_CTX *ctx = NULL;
    char *host = NULL, *port = NULL, *path = "/", buf[200];
    int err = ERR_OK, use_ssl = -1, rc;
    long e;

    //RETURN_IF_NULL_PARAM(pSendData); // may be null if nothing to send?
    RETURN_IF_NULL_PARAM(pRecvData);
    RETURN_IF_NULL_PARAM(url);

    ddocDebug(4, "ddocPullUrl", "URL: %s, in: %d bytes", url, pSendData->nLen);
    //there is an HTTP proxy - connect to that instead of the target host
    if (proxyHost != 0 && *proxyHost != '\0') {
        host = (char*)proxyHost;
        if(proxyPort != 0 && *proxyPort != '\0')
            port = (char*)proxyPort;
        path = (char*)url;
    } else {
        if(OCSP_parse_url((char*)url, &host, &port, &path, &use_ssl) == 0) {
            ddocDebug(1, "ddocPullUrl", "Failed to parse the URL");
            return ERR_WRONG_URL_OR_PROXY;
        }
    }

    if((cbio = BIO_new_connect(host)) != 0) {
        ddocDebug(4, "ddocPullUrl", "Host: %s port: %s", host, port);
        if(port != NULL) {
            BIO_set_conn_port(cbio, port);
        }
        if(use_ssl == 1) {
            ctx = SSL_CTX_new(SSLv23_client_method());
            SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
            sbio = BIO_new_ssl(ctx, 1);
            cbio = BIO_push(sbio, cbio);
        }
        if ((rc = BIO_do_connect(cbio)) > 0) {
            ddocDebug(4, "ddocPullUrl", "Connected: %d", rc);
            if(pSendData && pSendData->nLen && pSendData->pMem) {
                rc = BIO_write(cbio, pSendData->pMem, pSendData->nLen);
                ddocDebug(4, "ddocPullUrl", "Sent: %d bytes, got: %d", pSendData->nLen, rc);
            }
            do {
                memset(buf, 0, sizeof(buf));
                rc = BIO_read(cbio, buf, sizeof(buf)-1);
                ddocDebug(4, "ddocPullUrl", "Received: %d bytes\n", rc);
                if(rc > 0)
                    err = ddocMemAppendData(pRecvData, buf, rc);
            } while(rc > 0);
            ddocDebug(4, "ddocPullUrl", "Total received: %d bytes\n", pRecvData->nLen);
        } else {
            //if no connection
            e = checkErrors();
            if(ERR_GET_REASON(e) == BIO_R_BAD_HOSTNAME_LOOKUP ||
                    ERR_GET_REASON(e) == OCSP_R_SERVER_WRITE_ERROR)
                err = ERR_CONNECTION_FAILURE;
            else
                err = (host != NULL) ? ERR_WRONG_URL_OR_PROXY : ERR_CONNECTION_FAILURE;
        }
        BIO_free_all(cbio);
        if (use_ssl != -1) {
            OPENSSL_free(host);
            OPENSSL_free(port);
            OPENSSL_free(path);
            SSL_CTX_free(ctx);
        }
    }
    else
        err = ERR_CONNECTION_FAILURE;
    return(err);
}
Exemplo n.º 16
0
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	char **args;
	char *host = NULL, *port = NULL, *path = "/";
	char *reqin = NULL, *respin = NULL;
	char *reqout = NULL, *respout = NULL;
	char *signfile = NULL, *keyfile = NULL;
	char *rsignfile = NULL, *rkeyfile = NULL;
	char *outfile = NULL;
	int add_nonce = 1, noverify = 0, use_ssl = -1;
	OCSP_REQUEST *req = NULL;
	OCSP_RESPONSE *resp = NULL;
	OCSP_BASICRESP *bs = NULL;
	X509 *issuer = NULL, *cert = NULL;
	X509 *signer = NULL, *rsigner = NULL;
	EVP_PKEY *key = NULL, *rkey = NULL;
	BIO *acbio = NULL, *cbio = NULL;
	BIO *derbio = NULL;
	BIO *out = NULL;
	int req_text = 0, resp_text = 0;
	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
	char *CAfile = NULL, *CApath = NULL;
	X509_STORE *store = NULL;
	SSL_CTX *ctx = NULL;
	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
	int ret = 1;
	int accept_count = -1;
	int badarg = 0;
	int i;
	int ignore_err = 0;
	STACK *reqnames = NULL;
	STACK_OF(OCSP_CERTID) *ids = NULL;

	X509 *rca_cert = NULL;
	char *ridx_filename = NULL;
	char *rca_filename = NULL;
	CA_DB *rdb = NULL;
	int nmin = 0, ndays = -1;

	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	SSL_load_error_strings();
	OpenSSL_add_ssl_algorithms();
	args = argv + 1;
	reqnames = sk_new_null();
	ids = sk_OCSP_CERTID_new_null();
	while (!badarg && *args && *args[0] == '-')
		{
		if (!strcmp(*args, "-out"))
			{
			if (args[1])
				{
				args++;
				outfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-url"))
			{
			if (args[1])
				{
				args++;
				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
					{
					BIO_printf(bio_err, "Error parsing URL\n");
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-host"))
			{
			if (args[1])
				{
				args++;
				host = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-port"))
			{
			if (args[1])
				{
				args++;
				port = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-ignore_err"))
			ignore_err = 1;
		else if (!strcmp(*args, "-noverify"))
			noverify = 1;
		else if (!strcmp(*args, "-nonce"))
			add_nonce = 2;
		else if (!strcmp(*args, "-no_nonce"))
			add_nonce = 0;
		else if (!strcmp(*args, "-resp_no_certs"))
			rflags |= OCSP_NOCERTS;
		else if (!strcmp(*args, "-resp_key_id"))
			rflags |= OCSP_RESPID_KEY;
		else if (!strcmp(*args, "-no_certs"))
			sign_flags |= OCSP_NOCERTS;
		else if (!strcmp(*args, "-no_signature_verify"))
			verify_flags |= OCSP_NOSIGS;
		else if (!strcmp(*args, "-no_cert_verify"))
			verify_flags |= OCSP_NOVERIFY;
		else if (!strcmp(*args, "-no_chain"))
			verify_flags |= OCSP_NOCHAIN;
		else if (!strcmp(*args, "-no_cert_checks"))
			verify_flags |= OCSP_NOCHECKS;
		else if (!strcmp(*args, "-no_explicit"))
			verify_flags |= OCSP_NOEXPLICIT;
		else if (!strcmp(*args, "-trust_other"))
			verify_flags |= OCSP_TRUSTOTHER;
		else if (!strcmp(*args, "-no_intern"))
			verify_flags |= OCSP_NOINTERN;
		else if (!strcmp(*args, "-text"))
			{
			req_text = 1;
			resp_text = 1;
			}
		else if (!strcmp(*args, "-req_text"))
			req_text = 1;
		else if (!strcmp(*args, "-resp_text"))
			resp_text = 1;
		else if (!strcmp(*args, "-reqin"))
			{
			if (args[1])
				{
				args++;
				reqin = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-respin"))
			{
			if (args[1])
				{
				args++;
				respin = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-signer"))
			{
			if (args[1])
				{
				args++;
				signfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-VAfile"))
			{
			if (args[1])
				{
				args++;
				verify_certfile = *args;
				verify_flags |= OCSP_TRUSTOTHER;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-sign_other"))
			{
			if (args[1])
				{
				args++;
				sign_certfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-verify_other"))
			{
			if (args[1])
				{
				args++;
				verify_certfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-CAfile"))
			{
			if (args[1])
				{
				args++;
				CAfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-CApath"))
			{
			if (args[1])
				{
				args++;
				CApath = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-validity_period"))
			{
			if (args[1])
				{
				args++;
				nsec = atol(*args);
				if (nsec < 0)
					{
					BIO_printf(bio_err,
						"Illegal validity period %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-status_age"))
			{
			if (args[1])
				{
				args++;
				maxage = atol(*args);
				if (maxage < 0)
					{
					BIO_printf(bio_err,
						"Illegal validity age %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		 else if (!strcmp(*args, "-signkey"))
			{
			if (args[1])
				{
				args++;
				keyfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-reqout"))
			{
			if (args[1])
				{
				args++;
				reqout = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-respout"))
			{
			if (args[1])
				{
				args++;
				respout = *args;
				}
			else badarg = 1;
			}
		 else if (!strcmp(*args, "-path"))
			{
			if (args[1])
				{
				args++;
				path = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-issuer"))
			{
			if (args[1])
				{
				args++;
				X509_free(issuer);
				issuer = load_cert(bio_err, *args, FORMAT_PEM,
					NULL, e, "issuer certificate");
				if(!issuer) goto end;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-cert"))
			{
			if (args[1])
				{
				args++;
				X509_free(cert);
				cert = load_cert(bio_err, *args, FORMAT_PEM,
					NULL, e, "certificate");
				if(!cert) goto end;
				if(!add_ocsp_cert(&req, cert, issuer, ids))
					goto end;
				if(!sk_push(reqnames, *args))
					goto end;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-serial"))
			{
			if (args[1])
				{
				args++;
				if(!add_ocsp_serial(&req, *args, issuer, ids))
					goto end;
				if(!sk_push(reqnames, *args))
					goto end;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-index"))
			{
			if (args[1])
				{
				args++;
				ridx_filename = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-CA"))
			{
			if (args[1])
				{
				args++;
				rca_filename = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-nmin"))
			{
			if (args[1])
				{
				args++;
				nmin = atol(*args);
				if (nmin < 0)
					{
					BIO_printf(bio_err,
						"Illegal update period %s\n",
						*args);
					badarg = 1;
					}
				}
				if (ndays == -1)
					ndays = 0;
			else badarg = 1;
			}
		else if (!strcmp (*args, "-nrequest"))
			{
			if (args[1])
				{
				args++;
				accept_count = atol(*args);
				if (accept_count < 0)
					{
					BIO_printf(bio_err,
						"Illegal accept count %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-ndays"))
			{
			if (args[1])
				{
				args++;
				ndays = atol(*args);
				if (ndays < 0)
					{
					BIO_printf(bio_err,
						"Illegal update period %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-rsigner"))
			{
			if (args[1])
				{
				args++;
				rsignfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-rkey"))
			{
			if (args[1])
				{
				args++;
				rkeyfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-rother"))
			{
			if (args[1])
				{
				args++;
				rcertfile = *args;
				}
			else badarg = 1;
			}
		else badarg = 1;
		args++;
		}

	/* Have we anything to do? */
	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;

	if (badarg)
		{
		BIO_printf (bio_err, "OCSP utility\n");
		BIO_printf (bio_err, "Usage ocsp [options]\n");
		BIO_printf (bio_err, "where options are\n");
		BIO_printf (bio_err, "-out file          output filename\n");
		BIO_printf (bio_err, "-issuer file       issuer certificate\n");
		BIO_printf (bio_err, "-cert file         certificate to check\n");
		BIO_printf (bio_err, "-serial n          serial number to check\n");
		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
		BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
		BIO_printf (bio_err, "-req_text          print text form of request\n");
		BIO_printf (bio_err, "-resp_text         print text form of response\n");
		BIO_printf (bio_err, "-text              print text form of request and response\n");
		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
		BIO_printf (bio_err, "-path              path to use in OCSP request\n");
		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
		BIO_printf (bio_err, "-noverify          don't verify response at all\n");
		BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
		BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
		BIO_printf (bio_err, "-port num		 port to run responder on\n");
		BIO_printf (bio_err, "-index file	 certificate status index file\n");
		BIO_printf (bio_err, "-CA file		 CA certificate\n");
		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n");
		BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");
		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");
		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
		goto end;
		}

	if(outfile) out = BIO_new_file(outfile, "w");
	else out = BIO_new_fp(stdout, BIO_NOCLOSE);

	if(!out)
		{
		BIO_printf(bio_err, "Error opening output file\n");
		goto end;
		}

	if (!req && (add_nonce != 2)) add_nonce = 0;

	if (!req && reqin)
		{
		derbio = BIO_new_file(reqin, "rb");
		if (!derbio)
			{
			BIO_printf(bio_err, "Error Opening OCSP request file\n");
			goto end;
			}
		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
		BIO_free(derbio);
		if(!req)
			{
			BIO_printf(bio_err, "Error reading OCSP request\n");
			goto end;
			}
		}

	if (!req && port)
		{
		acbio = init_responder(port);
		if (!acbio)
			goto end;
		}

	if (rsignfile && !rdb)
		{
		if (!rkeyfile) rkeyfile = rsignfile;
		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
			NULL, e, "responder certificate");
		if (!rsigner)
			{
			BIO_printf(bio_err, "Error loading responder certificate\n");
			goto end;
			}
		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
			NULL, e, "CA certificate");
		if (rcertfile)
			{
			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
				NULL, e, "responder other certificates");
			if (!rother) goto end;
			}
		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
			"responder private key");
		if (!rkey)
			goto end;
		}
	if(acbio)
		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");

	redo_accept:

	if (acbio)
		{
		if (!do_responder(&req, &cbio, acbio, port))
			goto end;
		if (!req)
			{
			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
			send_ocsp_response(cbio, resp);
			goto done_resp;
			}
		}

	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
		{
		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
		goto end;
		}

	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);

	if (signfile)
		{
		if (!keyfile) keyfile = signfile;
		signer = load_cert(bio_err, signfile, FORMAT_PEM,
			NULL, e, "signer certificate");
		if (!signer)
			{
			BIO_printf(bio_err, "Error loading signer certificate\n");
			goto end;
			}
		if (sign_certfile)
			{
			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
				NULL, e, "signer certificates");
			if (!sign_other) goto end;
			}
		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
			"signer private key");
		if (!key)
			goto end;
		if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
			{
			BIO_printf(bio_err, "Error signing OCSP request\n");
			goto end;
			}
		}

	if (req_text && req) OCSP_REQUEST_print(out, req, 0);

	if (reqout)
		{
		derbio = BIO_new_file(reqout, "wb");
		if(!derbio)
			{
			BIO_printf(bio_err, "Error opening file %s\n", reqout);
			goto end;
			}
		i2d_OCSP_REQUEST_bio(derbio, req);
		BIO_free(derbio);
		}

	if (ridx_filename && (!rkey || !rsigner || !rca_cert))
		{
		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
		goto end;
		}

	if (ridx_filename && !rdb)
		{
		rdb = load_index(ridx_filename, NULL);
		if (!rdb) goto end;
		if (!index_index(rdb)) goto end;
		}

	if (rdb)
		{
		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
		if (cbio)
			send_ocsp_response(cbio, resp);
		}
	else if (host)
		{
#ifndef OPENSSL_NO_SOCK
		cbio = BIO_new_connect(host);
#else
		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
		goto end;
#endif
		if (!cbio)
			{
			BIO_printf(bio_err, "Error creating connect BIO\n");
			goto end;
			}
		if (port) BIO_set_conn_port(cbio, port);
		if (use_ssl == 1)
			{
			BIO *sbio;
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
			ctx = SSL_CTX_new(SSLv23_client_method());
#elif !defined(OPENSSL_NO_SSL3)
			ctx = SSL_CTX_new(SSLv3_client_method());
#elif !defined(OPENSSL_NO_SSL2)
			ctx = SSL_CTX_new(SSLv2_client_method());
#else
			BIO_printf(bio_err, "SSL is disabled\n");
			goto end;
#endif
			if (ctx == NULL)
				{
				BIO_printf(bio_err, "Error creating SSL context.\n");
				goto end;
				}
			SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
			sbio = BIO_new_ssl(ctx, 1);
			cbio = BIO_push(sbio, cbio);
			}
		if (BIO_do_connect(cbio) <= 0)
			{
			BIO_printf(bio_err, "Error connecting BIO\n");
			goto end;
			}
		resp = OCSP_sendreq_bio(cbio, path, req);
		BIO_free_all(cbio);
		cbio = NULL;
		if (!resp)
			{
			BIO_printf(bio_err, "Error querying OCSP responsder\n");
			goto end;
			}
		}
	else if (respin)
		{
		derbio = BIO_new_file(respin, "rb");
		if (!derbio)
			{
			BIO_printf(bio_err, "Error Opening OCSP response file\n");
			goto end;
			}
		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
		BIO_free(derbio);
		if(!resp)
			{
			BIO_printf(bio_err, "Error reading OCSP response\n");
			goto end;
			}
	
		}
	else
		{
		ret = 0;
		goto end;
		}

	done_resp:

	if (respout)
		{
		derbio = BIO_new_file(respout, "wb");
		if(!derbio)
			{
			BIO_printf(bio_err, "Error opening file %s\n", respout);
			goto end;
			}
		i2d_OCSP_RESPONSE_bio(derbio, resp);
		BIO_free(derbio);
		}

	i = OCSP_response_status(resp);

	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
		{
		BIO_printf(out, "Responder Error: %s (%d)\n",
				OCSP_response_status_str(i), i);
		if (ignore_err)
			goto redo_accept;
		ret = 0;
		goto end;
		}

	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);

	/* If running as responder don't verify our own response */
	if (cbio)
		{
		if (accept_count > 0)
			accept_count--;
		/* Redo if more connections needed */
		if (accept_count)
			{
			BIO_free_all(cbio);
			cbio = NULL;
			OCSP_REQUEST_free(req);
			req = NULL;
			OCSP_RESPONSE_free(resp);
			resp = NULL;
			goto redo_accept;
			}
		goto end;
		}

	if (!store)
		store = setup_verify(bio_err, CAfile, CApath);
	if (!store)
		goto end;
	if (verify_certfile)
		{
		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
			NULL, e, "validator certificate");
		if (!verify_other) goto end;
		}

	bs = OCSP_response_get1_basic(resp);

	if (!bs)
		{
		BIO_printf(bio_err, "Error parsing response\n");
		goto end;
		}

	if (!noverify)
		{
		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
			{
			if (i == -1)
				BIO_printf(bio_err, "WARNING: no nonce in response\n");
			else
				{
				BIO_printf(bio_err, "Nonce Verify error\n");
				goto end;
				}
			}

		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
                if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);

		if(i <= 0)
			{
			BIO_printf(bio_err, "Response Verify Failure\n");
			ERR_print_errors(bio_err);
			}
		else
			BIO_printf(bio_err, "Response verify OK\n");

		}

	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
		goto end;

	ret = 0;

end:
	ERR_print_errors(bio_err);
	X509_free(signer);
	X509_STORE_free(store);
	EVP_PKEY_free(key);
	EVP_PKEY_free(rkey);
	X509_free(issuer);
	X509_free(cert);
	X509_free(rsigner);
	X509_free(rca_cert);
	free_index(rdb);
	BIO_free_all(cbio);
	BIO_free_all(acbio);
	BIO_free(out);
	OCSP_REQUEST_free(req);
	OCSP_RESPONSE_free(resp);
	OCSP_BASICRESP_free(bs);
	sk_free(reqnames);
	sk_OCSP_CERTID_free(ids);
	sk_X509_pop_free(sign_other, X509_free);
	sk_X509_pop_free(verify_other, X509_free);

	if (use_ssl != -1)
		{
		OPENSSL_free(host);
		OPENSSL_free(port);
		OPENSSL_free(path);
		SSL_CTX_free(ctx);
		}

	OPENSSL_EXIT(ret);
}
Exemplo n.º 17
0
static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
	{
	BIO *dbio;
	int *ip;
	const char **pptr;
	long ret=1;
	BIO_CONNECT *data;

	data=(BIO_CONNECT *)b->ptr;

	switch (cmd)
		{
	case BIO_CTRL_RESET:
		ret=0;
		data->state=BIO_CONN_S_BEFORE;
		conn_close_socket(b);
		b->flags=0;
		break;
	case BIO_C_DO_STATE_MACHINE:
		/* use this one to start the connection */
		if (!data->state != BIO_CONN_S_OK)
			ret=(long)conn_state(b,data);
		else
			ret=1;
		break;
	case BIO_C_GET_CONNECT:
		if (ptr != NULL)
			{
			pptr=(const char **)ptr;
			if (num == 0)
				{
				*pptr=data->param_hostname;

				}
			else if (num == 1)
				{
				*pptr=data->param_port;
				}
			else if (num == 2)
				{
				*pptr= (char *)&(data->ip[0]);
				}
			else if (num == 3)
				{
				*((int *)ptr)=data->port;
				}
			if ((!b->init) || (ptr == NULL))
				*pptr="not initialized";
			ret=1;
			}
		break;
	case BIO_C_SET_CONNECT:
		if (ptr != NULL)
			{
			b->init=1;
			if (num == 0)
				{
				if (data->param_hostname != NULL)
					OPENSSL_free(data->param_hostname);
				data->param_hostname=BUF_strdup(ptr);
				}
			else if (num == 1)
				{
				if (data->param_port != NULL)
					OPENSSL_free(data->param_port);
				data->param_port=BUF_strdup(ptr);
				}
			else if (num == 2)
				{
				char buf[16];
				unsigned char *p = ptr;

				BIO_snprintf(buf,sizeof buf,"%d.%d.%d.%d",
					     p[0],p[1],p[2],p[3]);
				if (data->param_hostname != NULL)
					OPENSSL_free(data->param_hostname);
				data->param_hostname=BUF_strdup(buf);
				memcpy(&(data->ip[0]),ptr,4);
				}
			else if (num == 3)
				{
				char buf[DECIMAL_SIZE(int)+1];

				BIO_snprintf(buf,sizeof buf,"%d",*(int *)ptr);
				if (data->param_port != NULL)
					OPENSSL_free(data->param_port);
				data->param_port=BUF_strdup(buf);
				data->port= *(int *)ptr;
				}
			}
		break;
	case BIO_C_SET_NBIO:
		data->nbio=(int)num;
		break;
	case BIO_C_GET_FD:
		if (b->init)
			{
			ip=(int *)ptr;
			if (ip != NULL)
				*ip=b->num;
			ret=b->num;
			}
		else
			ret= -1;
		break;
	case BIO_CTRL_GET_CLOSE:
		ret=b->shutdown;
		break;
	case BIO_CTRL_SET_CLOSE:
		b->shutdown=(int)num;
		break;
	case BIO_CTRL_PENDING:
	case BIO_CTRL_WPENDING:
		ret=0;
		break;
	case BIO_CTRL_FLUSH:
		break;
	case BIO_CTRL_DUP:
		{
		dbio=(BIO *)ptr;
		if (data->param_port)
			BIO_set_conn_port(dbio,data->param_port);
		if (data->param_hostname)
			BIO_set_conn_hostname(dbio,data->param_hostname);
		BIO_set_nbio(dbio,data->nbio);
		/* FIXME: the cast of the function seems unlikely to be a good idea */
                (void)BIO_set_info_callback(dbio,(bio_info_cb *)data->info_callback);
		}
		break;
	case BIO_CTRL_SET_CALLBACK:
		{
#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
		BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		ret = -1;
#else
		ret=0;
#endif
		}
		break;
	case BIO_CTRL_GET_CALLBACK:
		{
		int (**fptr)();

		fptr=(int (**)())ptr;
		*fptr=data->info_callback;
		}
		break;
	default:
		ret=0;
		break;
		}
	return(ret);
	}
Exemplo n.º 18
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));  
}
Exemplo n.º 19
0
int main(int argc, char **argv)  
{
    BIO *sslbio;
    SSL_CTX *ctx;  
    SSL *ssl;  
    //SSL_METHOD *meth;  
    unsigned long totl;  
    int i, p;
    char hostname[BUF_SIZE + 1];
    char server[16];
    char choice;
    int ret;    

  
    if (argc != 2) {  
        printf("Usage: %s ClientName\n", argv[0]);  
        printf("eg: '%s client1'\n", argv[0]);  
        return -1;  
    }

    if (strlen(argv[1]) >= NAME_SIZE) {
        fprintf(stderr, "%s is too long! \nPick a shorter client name.\n",argv[1]);
    } else {
        strcpy(CLIENT_NAME, argv[1]);    
    }
    printf("client name: %s\n", CLIENT_NAME);

    /* Formatting required certificates for client ...
       certificates are matched to client with file names */
    int length = strlen(CLIENT_NAME) + 10;
    char CLIENT_CERT_FILE2[length];
    strcpy(CLIENT_CERT_FILE2, "cert/");
    strcat(CLIENT_CERT_FILE2, CLIENT_NAME);
    strcat(CLIENT_CERT_FILE2, ".pem");
    printf("This client CERT file is required: %s\n", CLIENT_CERT_FILE2);
    // Checking for required certificate
    if( access( CLIENT_CERT_FILE2, F_OK ) != -1 ) {
    // file exists
	printf("CERT file verified present\n");
    } else {
    // file doesn't exist
	printf("CERT NOT FOUND....\n"
		"Perhaps this client does not have valid\n"
		"certificates present at this location\n"
		">>> ./%s\n",CLIENT_CERT_FILE2);
	exit(4);
    }
    char CLIENT_KEY_FILE2[length];
    strcpy(CLIENT_KEY_FILE2, "cert/");
    strcat(CLIENT_KEY_FILE2, CLIENT_NAME);
    strcat(CLIENT_KEY_FILE2, ".key");
    printf("This client KEY file is required: %s\n", CLIENT_KEY_FILE2);
    // Checking for required certificate
    if( access( CLIENT_KEY_FILE2, F_OK ) != -1 ) {
    // file exists
	printf("KEY file verified present\n\n");
    } else {
    // file doesn't exist
	printf("KEY NOT FOUND....\n"
		"Perhaps this client does not have valid"
		"certificates present at this location\n"
		">>> ./%s\n",CLIENT_KEY_FILE2);
	exit(4);
    }

    /* Give initial menu to user; get hostname for connection */
    choice = getchoice("Please select an action", imenu);
    printf("You have chosen: %c\n", choice);
    if (choice == 'q')
    {
	printf("Ending Program... Goodbye.\n");
    } 
    else // choice == 'a' 
    {
	printf("Initializing connection...\n");
    
	// NOTE: 45 is the max length of a IPv4 address
        getInput(server, "Enter server hostname to connect \n (e.g., '127.0.0.1')", 15);
    	SSL_library_init();  
    	ERR_load_BIO_strings();
    	ERR_load_SSL_strings();  
    	SSL_load_error_strings();
    	OpenSSL_add_all_algorithms();
	ctx = SSL_CTX_new(SSLv3_client_method()); 
//    	ctx = SSL_CTX_new(SSLv3_method());
    	  
    	//ctx = SSL_CTX_new(meth);  
    	assert(ctx != NULL);  
          
    	/* Verify the server */  
    	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);  
    	/* Load CA Certificate */  
    	if (!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL)) {  
            printf("Load CA file failed.\r\n");  
            //goto free_ctx;
            BIO_free_all(sslbio);
            SSL_CTX_free(ctx);
            return 0;
        }  
  

    	/* Load Client Certificate with Public Key */  
    	if (SSL_CTX_use_certificate_file(ctx, CLIENT_CERT_FILE2, SSL_FILETYPE_PEM) <= 0) {  
            ERR_print_errors_fp(stdout);  
            printf("ssl_ctx_use_certificate_file failed.\r\n");  
            //goto free_ctx;
            BIO_free_all(sslbio);
            SSL_CTX_free(ctx);
            return 0;  
        }  
  
      
    	/* Load Private Key */  
    	if (SSL_CTX_use_PrivateKey_file(ctx, CLIENT_KEY_FILE2, SSL_FILETYPE_PEM) <= 0) {  
            ERR_print_errors_fp(stdout);  
            printf("ssl_ctx_use_privatekey_file failed.\r\n");  
            //goto free_ctx;
            BIO_free_all(sslbio);
            SSL_CTX_free(ctx);
            return 0;
        }  
  
      
    	/* Check the validity of Private Key */  
    	if (!SSL_CTX_check_private_key(ctx)) {  
            ERR_print_errors_fp(stdout);  
            printf("ssl_ctx_check_private_key failed.\r\n");  
            //goto free_ctx;
            BIO_free_all(sslbio);
            SSL_CTX_free(ctx);
            return 0;  
    	}

    	/* Create the connection */
    	sslbio = BIO_new_ssl_connect(ctx);
    	/* Get SSL from sslbio */
    	BIO_get_ssl(sslbio, &ssl);
    	/* Set the SSL mode into SSL_MODE_AUTO_RETRY */
    	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
 
    	//////////////////////////////////////////////////
    	// NOTE: Port# hardcoded here; change if necessary
    	////////////////////////////////////////////////// 
    	BIO_set_conn_port(sslbio, "7777");
    	BIO_set_conn_hostname(sslbio, server);
	
	/* Request Connection */
	if(BIO_do_connect(sslbio) <= 0)
    	{
            fprintf(stderr, "Error attempting to connect\n");
            ERR_print_errors_fp(stderr);
            BIO_free_all(sslbio);
            SSL_CTX_free(ctx);
            return 0;
    	}
    	else
    	{
            printf("Connection to server successful!\n");
    	}

    	/* Verify Server Certificate Validity */
    	if(SSL_get_verify_result(ssl) != X509_V_OK)
    	{
            printf("Certificate Verification Error: %ld\n", SSL_get_verify_result(ssl));
            BIO_free_all(sslbio);
            SSL_CTX_free(ctx);
            return 0;
    	}
    	else
    	{
    	    printf("verify server cert successful\n");
    	}

    	//Send hostname to server
    	printf("Sending client name to server.\n");
    	BIO_write(sslbio, CLIENT_NAME, strlen(CLIENT_NAME));
  
    	do
    	{
    	    choice = getchoice("Please select an action", menu);
    	    printf("You have chosen: %c\n", choice);
	
	    if (choice == 'a')
	    {
        	printf("Check-in function will be executed\n");
                choiceProcess (sslbio, buffer, choice);
                ret = checkin_file(ssl, sslbio, buffer);
            }
            else if (choice == 'b')
            {
                printf("Check-out function will be executed\n");
                choiceProcess (sslbio, buffer, choice);
		ret = checkout_file(ssl, sslbio, buffer);
            }
            else if (choice == 'c')
            {
                printf("Delegate function will be executed\n");
                choiceProcess (sslbio, buffer, choice);
            }
            else if (choice == 'd')
            {
                printf("Safe-delete function will be executed\n");
                choiceProcess (sslbio, buffer, choice);
            }
            else
            {
                printf("Terminate function will be executed\n");
            }

        } while (choice != 'q');

        /* Terminate the connection by sending message */
        clientTerminate (sslbio, buffer);

        /* Close the connection and free the context */
        BIO_ssl_shutdown(sslbio);
        BIO_free_all(sslbio);
    	SSL_CTX_free(ctx);
    }

    return 0;  
} 
Exemplo n.º 20
0
/** Returns status of ticket by filling 'buf' with a NetID if the ticket
 *  is valid and buf is large enough and returning 1.  If not, 0 is
 *  returned.
 */
int cas_validate(
    char *ticket, char *service, char *outbuf, int outbuflen, pam_cas_config_t *config)
{
  int b, ret, total;
  SSL_CTX *ctx = NULL;
  BIO * bio = NULL;
  SSL *ssl = NULL;
  char buf[4096];
  char *full_request = NULL, *str;
  char netid[CAS_LEN_NETID];
  char parsebuf[128];

  debug = config->debug;

  if (config->ssl)
  {
    DEBUG_LOG("We use SSL as configured\n", "");
    /* Set up the SSL library */
    ERR_load_BIO_strings();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();
#if defined(OpenSSL_add_ssl_algorithms)
    OpenSSL_add_ssl_algorithms();
#endif

    /* Set up the SSL context */
    ctx = SSL_CTX_new(SSLv23_client_method());
    if ( ! ctx ) 
    {
      DEBUG_LOG("Cannot create SSL context", "");
      END(CAS_SSL_ERROR_INIT);
    }

    /* Load the trust store */
    if(! SSL_CTX_load_verify_locations(ctx, config->trusted_ca, NULL))
    {
      DEBUG_LOG("Error loading certificate store : %s\n", ERR_reason_error_string(ERR_get_error()));
      END(CAS_SSL_ERROR_CERT_LOAD);
    }

    /* Setup the connection */
    bio = BIO_new_ssl_connect(ctx);

    /* Set the SSL_MODE_AUTO_RETRY flag :
       if the server suddenly wants a new handshake, OpenSSL handles it in the background */
    BIO_get_ssl(bio, & ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    /* Create and setup the connection */
    DEBUG_LOG("We connect to host %s\n", config->host);
    BIO_set_conn_hostname(bio, config->host);
    BIO_set_conn_port(bio, config->port);
    if(BIO_do_connect(bio) <= 0)
    {
      DEBUG_LOG("Error attempting to connect : %s\n", ERR_reason_error_string(ERR_get_error()));
      END(CAS_SSL_ERROR_CONN);
    }

    /* Check the certificate */
    if (SSL_get_verify_result(ssl) != X509_V_OK)
    {
      DEBUG_LOG("Certificate verification error: %ld\n", SSL_get_verify_result(ssl));
      END(CAS_SSL_ERROR_CERT_VALID);
    }
  }
  else  /* no ssl */
  {    
    bio = BIO_new_connect(config->host);
    BIO_set_conn_port(bio, config->port);
    if(BIO_do_connect(bio) <= 0)
    {
      DEBUG_LOG("Error attempting to connect : %s\n", config->host);
      END(CAS_ERROR_CONN);
    }
  }

  /* build request */
  full_request = malloc(strlen(CAS_METHOD) + strlen(" ")
    + strlen(config->uriValidate) + strlen("?ticket=") + strlen(ticket) + 
    + strlen("&service=") + strlen(service) + strlen(" ") 
    + strlen(GENERIC_HEADERS) + strlen ("\r\n")
#ifdef HEADER_HOST_NAME
    + strlen(HEADER_HOST_NAME) + strlen (": ") + strlen (config->host)
#endif
    + strlen("\r\n\r\n") + 1);
  if (full_request == NULL)
  {
      DEBUG_LOG("Error memory allocation%s\n", "");
      END(CAS_ERROR_MEMORY_ALLOC);
  }
#ifdef HEADER_HOST_NAME
  sprintf(full_request, "%s %s?ticket=%s&service=%s %s\r\n%s: %s\r\n\r\n",
	  CAS_METHOD, config->uriValidate, ticket, service, GENERIC_HEADERS,
          HEADER_HOST_NAME,config->host);
#else
  sprintf(full_request, "%s %s?ticket=%s&service=%s %s\r\n\r\n",
	  CAS_METHOD, config->uriValidate, ticket, service, GENERIC_HEADERS);
#endif

  /* send request */
  DEBUG_LOG("---- request :\n%s\n", full_request);
  if (BIO_write(bio, full_request, strlen(full_request)) != strlen(full_request))
  {
    DEBUG_LOG("Unable to correctly send request to %s\n", config->host);
    END(CAS_ERROR_HTTP);
  }

  /* Read the response */
  total = 0;
  b = 0;
  do 
  {
    b = BIO_read(bio, buf + total, (sizeof(buf) - 1) - total);
    total += b;
  } while (b > 0);
  buf[total] = '\0';

  if (b != 0 || total >= sizeof(buf) - 1)
  {
    DEBUG_LOG("Unexpected read error or response too large from %s\n", config->host);
    DEBUG_LOG("b = %d\n", b);
    DEBUG_LOG("total = %d\n", total);
    DEBUG_LOG("buf = %s\n", buf);
    END(CAS_ERROR_HTTP);		// unexpected read error or response too large
  }

  DEBUG_LOG("---- response :\n%s\n", buf);
  str = (char *)strstr(buf, "\r\n\r\n");  // find the end of the header

  if (!str)
  {
    DEBUG_LOG("no header in response%s\n", "");
    END(CAS_ERROR_HTTP);			  // no header
  }

  /*
   * 'str' now points to the beginning of the body, which should be an
   * XML document
   */

  // make sure that the authentication succeeded
  
  if (!element_body(
    str, "cas:authenticationSuccess", 1, parsebuf, sizeof(parsebuf))) {
    END(CAS_BAD_TICKET);
  }

  // retrieve the NetID
  if (!element_body(str, "cas:user", 1, netid, sizeof(netid))) {
    DEBUG_LOG("unable to determine username%s\n", "");
    END(CAS_PROTOCOL_FAILURE);
  }


  // check the first proxy (if present)
  if ((config->proxies) && (config->proxies[0]))
    if (element_body(str, "cas:proxies", 1, parsebuf, sizeof(parsebuf)))
      if (element_body(str, "cas:proxy", 1, parsebuf, sizeof(parsebuf)))
        if (!arrayContains(config->proxies, parsebuf)) {
          DEBUG_LOG("bad proxy: %s\n", parsebuf);
          END(CAS_BAD_PROXY);
        }

  /*
   * without enough space, fail entirely, since a partial NetID could
   * be dangerous
   */
  if (outbuflen < strlen(netid) + 1) 
  {
    syslog(LOG_ERR, "output buffer too short");
    DEBUG_LOG("output buffer too short%s\n", "");
    END(CAS_PROTOCOL_FAILURE);
  }

  strcpy(outbuf, netid);
  SUCCEED;

   /* cleanup and return */

end:
  if (ctx)
    SSL_CTX_free(ctx);
  if (bio)
    BIO_free_all(bio);
  if (full_request)
    free(full_request);
  return ret;
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
/*
 * Establishes the connection to the Duo server.  On successful return,
 * req->cbio is connected and ready to use.
 * Return HTTPS_OK on success, error code on failure.
 */
static HTTPScode
_establish_connection(struct https_request * const req,
        const char * const api_host,
        const char * const api_port)
{
#ifndef HAVE_GETADDRINFO
    /* Systems that don't have getaddrinfo can use the BIO
       wrappers, but only get IPv4 support. */
    int n;

    if ((req->cbio = BIO_new(BIO_s_connect())) == NULL) {
        ctx->errstr = _SSL_strerror();
        return HTTPS_ERR_LIB;
    }
    BIO_set_conn_hostname(req->cbio, api_host);
    BIO_set_conn_port(req->cbio, api_port);
    BIO_set_nbio(req->cbio, 1);

    while (BIO_do_connect(req->cbio) <= 0) {
        if ((n = _BIO_wait(req->cbio, 10000)) != 1) {
            ctx->errstr = n ? _SSL_strerror() :
                "Connection timed out";
            return (n ? HTTPS_ERR_SYSTEM : HTTPS_ERR_SERVER);
        }
    }

    return HTTPS_OK;

#else /* HAVE_GETADDRINFO */

    /* IPv6 Support
     * BIO wrapped io does not support IPv6 addressing.  To work around,
     * resolve the address and connect the socket manually.  Then pass
     * the connected socket to the BIO wrapper with BIO_new_socket.
     */
    int connected_socket = -1;
    int socket_error = 0;
    /* Address Lookup */
    struct addrinfo *res = NULL;
    struct addrinfo *cur_res = NULL;
    struct addrinfo hints;
    int error;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    error = getaddrinfo(api_host,
            api_port,
            &hints,
            &res);
    if (error) {
        ctx->errstr = gai_strerror(error);
        return HTTPS_ERR_SYSTEM;
    }

    /* Connect */
    for (cur_res = res; cur_res; cur_res = cur_res->ai_next) {
        int connretries = 3;
        while (connected_socket == -1 && connretries--) {
            int sock_flags;

            connected_socket = socket(cur_res->ai_family,
                    cur_res->ai_socktype,
                    cur_res->ai_protocol);
            if (connected_socket == -1) {
                continue;
            }
            sock_flags = fcntl(connected_socket, F_GETFL, 0);
            fcntl(connected_socket, F_SETFL, sock_flags|O_NONBLOCK);

            if (connect(connected_socket, cur_res->ai_addr, cur_res->ai_addrlen) != 0 &&
                    errno != EINPROGRESS) {
                close(connected_socket);
                connected_socket = -1;
                break;
            }
            socket_error = _fd_wait(connected_socket, 10000);
            if (socket_error != 1) {
                close(connected_socket);
                connected_socket = -1;
                continue;
            }
            /* Connected! */
            break;
        }
    }
    cur_res = NULL;
    freeaddrinfo(res);
    res = NULL;

    if (connected_socket == -1) {
        ctx->errstr = "Failed to connect";
        return socket_error ? HTTPS_ERR_SYSTEM : HTTPS_ERR_SERVER;
    }

    if ((req->cbio = BIO_new_socket(connected_socket, BIO_CLOSE)) == NULL) {
        ctx->errstr = _SSL_strerror();
        return (HTTPS_ERR_LIB);
    }
    BIO_set_conn_hostname(req->cbio, api_host);
    BIO_set_conn_port(req->cbio, api_port);
    BIO_set_nbio(req->cbio, 1);

    return HTTPS_OK;

#endif /* HAVE_GETADDRINFO */
}
enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t *pb)
{
    SSL *ssl = NULL;
    int rslt;
    char const* origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN;

    PUBNUB_ASSERT(pb_valid_ctx_ptr(pb));
    PUBNUB_ASSERT_OPT((pb->state == PBS_READY) || (pb->state == PBS_WAIT_CONNECT));

    if (!pb->options.useSSL) {
        return resolv_and_connect_wout_SSL(pb);
    }

    if (NULL == pb->pal.ctx) {
        PUBNUB_LOG_TRACE("pb=%p: Don't have SSL_CTX\n", pb);
        pb->pal.ctx = SSL_CTX_new(SSLv23_client_method());
        if (NULL == pb->pal.ctx) {
            ERR_print_errors_cb(print_to_pubnub_log, NULL);
            PUBNUB_LOG_ERROR("pb=%p SSL_CTX_new failed\n", pb);
            return pbpal_resolv_resource_failure;
        }
        PUBNUB_LOG_TRACE("pb=%p: Got SSL_CTX\n", pb);
        add_pubnub_cert(pb->pal.ctx);
    }

    if (NULL == pb->pal.socket) {
        PUBNUB_LOG_TRACE("pb=%p: Don't have BIO\n", pb);
        pb->pal.socket = BIO_new_ssl_connect(pb->pal.ctx);
        if (PUBNUB_TIMERS_API) {
            pb->pal.connect_timeout = time(NULL)  + pb->transaction_timeout_ms/1000;
        }
    }
    else {
        BIO_get_ssl(pb->pal.socket, &ssl);
        if (NULL == ssl) {
            return resolv_and_connect_wout_SSL(pb);
        }
        ssl = NULL;
    }
    if (NULL == pb->pal.socket) {
        ERR_print_errors_cb(print_to_pubnub_log, NULL);
        return pbpal_resolv_resource_failure;
    }

    PUBNUB_LOG_TRACE("pb=%p: Using BIO == %p\n", pb, pb->pal.socket);

    BIO_get_ssl(pb->pal.socket, &ssl);
    PUBNUB_ASSERT(NULL != ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* maybe not auto_retry? */
    if (pb->pal.session != NULL) {
        SSL_set_session(ssl, pb->pal.session);
    }

    BIO_set_conn_hostname(pb->pal.socket, origin);
    BIO_set_conn_port(pb->pal.socket, "https");
    if (pb->pal.ip_timeout != 0) {
        if (pb->pal.ip_timeout < time(NULL)) {
            pb->pal.ip_timeout = 0;
        }
        else {
            PUBNUB_LOG_TRACE("SSL re-connect to: %d.%d.%d.%d\n", pb->pal.ip[0], pb->pal.ip[1], pb->pal.ip[2], pb->pal.ip[3]);
            BIO_set_conn_ip(pb->pal.socket, pb->pal.ip);
        }
    }
    
    BIO_set_nbio(pb->pal.socket, !pb->options.use_blocking_io);
    
    WATCH_ENUM(pb->options.use_blocking_io);
    if (BIO_do_connect(pb->pal.socket) <= 0) {
        if (BIO_should_retry(pb->pal.socket) && PUBNUB_TIMERS_API && (pb->pal.connect_timeout > time(NULL))) {
            PUBNUB_LOG_TRACE("pb=%p: BIO_should_retry\n", pb);
            return pbpal_connect_wouldblock;
        }
        /* Expire the IP for the next connect */
        pb->pal.ip_timeout = 0;
        ERR_print_errors_cb(print_to_pubnub_log, NULL);
        if (pb->pal.session != NULL) {
            SSL_SESSION_free(pb->pal.session);
            pb->pal.session = NULL;
        }
        PUBNUB_LOG_ERROR("pb=%p: BIO_do_connect failed\n", pb);
        return pbpal_connect_failed;
    }

    PUBNUB_LOG_TRACE("pb=%p: BIO connected\n", pb);
    {
        int fd = BIO_get_fd(pb->pal.socket, NULL);
        socket_set_rcv_timeout(fd, pb->transaction_timeout_ms);
    }

    rslt = SSL_get_verify_result(ssl);
    if (rslt != X509_V_OK) {
        PUBNUB_LOG_WARNING("pb=%p: SSL_get_verify_result() failed == %d(%s)\n", pb, rslt, X509_verify_cert_error_string(rslt));
        ERR_print_errors_cb(print_to_pubnub_log, NULL);
        if (pb->options.fallbackSSL) {
            BIO_free_all(pb->pal.socket);
            pb->pal.socket = NULL;
            return resolv_and_connect_wout_SSL(pb);
        }
        return pbpal_connect_failed;
    }

    PUBNUB_LOG_INFO("pb=%p: SSL session reused: %s\n", pb, SSL_session_reused(ssl) ? "yes" : "no");
    if (pb->pal.session != NULL) {
        SSL_SESSION_free(pb->pal.session);
    }
    pb->pal.session = SSL_get1_session(ssl);
    if (0 == pb->pal.ip_timeout) {
        pb->pal.ip_timeout = SSL_SESSION_get_time(pb->pal.session) + SSL_SESSION_get_timeout(pb->pal.session);
        memcpy(pb->pal.ip, BIO_get_conn_ip(pb->pal.socket), 4);
    }
    PUBNUB_LOG_TRACE("pb=%p: SSL connected to IP: %d.%d.%d.%d\n", pb, pb->pal.ip[0], pb->pal.ip[1], pb->pal.ip[2], pb->pal.ip[3]);

    return pbpal_connect_success;
}