Exemple #1
0
int main(int argc, char *argv[])
{
	BIO *acc, *client;
	pthread_t pid;

	init_OpenSSL();
	acc = BIO_new_accept(PORT);
	if(!acc)
		int_error("Error creating server socket");

	if(BIO_do_accept(acc)<=0)
		int_error("Error binding server socket");

	for(;;)
	{
		if(BIO_do_accept(acc)<=0)
			int_error("Error accepting connection");

		client=BIO_pop(acc);
		pthread_create(&pid, NULL, server_thread, client);
	}

	BIO_free(acc);
	return 0;
}
Exemple #2
0
int receiveFile(char *socket, char *outfile)
{
  BIO *receive = BIO_new_accept(socket);
  BIO *fileout = BIO_new_file(outfile,"w");
  
  // it seems you need to do this twice.. not sure why, but we do
  // guess I'll try figure out why at some point
  if (BIO_do_accept(receive) <= 0) {
    fprintf(stderr, "Error setting up accept\n");
    exit(0);
  }
  if (BIO_do_accept(receive) <= 0) {
    fprintf(stderr, "Error setting up accept\n");
    exit(0);
  }


  char tmpbuf[BUFSIZ];

  // magic wrapper
  BIO *bufbio = BIO_new(BIO_f_buffer());
  BIO_push(bufbio, receive);

  //read in the file length and store
  BIO_gets(bufbio, tmpbuf, BUFSIZ);
  printf("Getting file length: %s\n", tmpbuf);

  unsigned int size = atoi(tmpbuf);

  transmit(bufbio, fileout, size);

  BIO_flush(fileout);
  BIO_free(bufbio);
  return 1;
}
Exemple #3
0
int main(int argc, char **argv) {

	BIO *acc, *client;
	THREAD_TYPE tid;
	
	init_OpenSSL();
	
	acc = BIO_new_accept(SERV_PORT);
	if(!acc) {
		int_error("Error creating server socket.\n");
	}

	if(BIO_do_accept(acc) <= 0) {
		int_error("Error binding server socket.\n");
	}

	for(;;) {

		if(BIO_do_accept(acc) <= 0) {
			int_error("Error accepting connection from client.\n");
		}
		
		client = BIO_pop(acc);
		THREAD_CREATE(tid, server_thread, client);
	}

	BIO_free(acc);
	return 0;
}
Exemple #4
0
int main(int argc, char **argv)
{
    BIO *acc, *client;
    SSL *ssl;
    SSL_CTX *ctx;
    pthread_t tid;

    init_openssl();
    seed_prng(64);

    ctx = setup_server_ctx();
    acc = BIO_new_accept(PORT);
    if(!acc)
        log_err("Error creating server socket.");

    /* first call BIO_do_accept() setup accept BIO */
    if(BIO_do_accept(acc) <= 0)
        log_err("Error binding server socket.");

    for(;;) {
        if(BIO_do_accept(acc) <= 0)
            log_err("Error accepting connection.");
        client = BIO_pop(acc);
        if(!(ssl = SSL_new(ctx)))
            log_err("Error creating SSL context.");
        SSL_set_bio(ssl, client, client);
        pthread_create(&tid, NULL, server_thread, ssl);
    }

    SSL_CTX_free(ctx);
    BIO_free(acc);
    return 0;
}
Exemple #5
0
int main(int argc, char *argv[])
{

	BIO *server, *client;
	SSL *ssl;
	SSL_CTX *ctx;
	pthread_t tid;

	init_OpenSSL();

	/*
	 *	It creates a new accept BIO with port host_port
	 */
	server = BIO_new_accept("9104");

	if (!server)
		error("Error creating server socket");

	/*
	 *	BIO_do_accept() serves two functions. When it is first called, after the accept
	 *	BIO has been setup, it will attempt to create the accept socket and bind an 
	 *	address to it. Second and subsequent calls to BIO_do_accept() will await an
	 *	incoming connection,or request a retry in non blocking mode
	 */
	if (BIO_do_accept(server) <= 0)
		error("Setup BIO in Accepting Mode\n");
	for (;;)
	{
		if (BIO_do_accept(server) <= 0)
			error("Error Accepting Connection\n");
		/*
		 * When a connection is established a new socket BIO is created for the 
		 * connection and appended to the chain.
		 * BIO_pop removes the BIO b from a chain and returns the next BIO in the
		 * chain.
		 */
		client = BIO_pop(server);
		/*
		 *Now client here is containing a BIO for the recently established connection
		 *and server will now be a single BIO again which can be used to await further
		 *incoming connections
		 */
		pthread_create(&tid, NULL, (void *)server_thread, client);
	}
	/*
	 *	Close the connection
	 */
	BIO_free(server);
	return 0;
}
/*
  The first line specifiy some settings in the ctx and ssl object:
  SSL_OP_ALL: enables all work around codes
  SSL_OP_NO_SSLv2: no SSLv2 connections are allowed (this should fail anyway because only
                   TLSv1 connection are allowed)
  SSL_OP_SINGLE_DH_USE: the server generates a new private key for each new connection
  SSL_VERIFY_PEER: asks the client for a certificate
  SSL_VERIFY_FAIL_IF_NO_PEER_CERT: if the client doesn't present a cert the connection gets
                                   terminated
  CIPHER_LIST: is defined in ssl_server.h (look there for a detailed description)

  After setting up these things the bio object will be created and a ssl object assigned.
  Then the ssl engine mode is set to SSL_MODE_AUTO_RETRY. All available modes are:

  SSL_MODE_ENABLE_PARTIAL_WRITE: Allow SSL_write(..., n) to return r with 0 < r < n 
                                (i.e. report success when just a single record has been written).
				When not set (the default), SSL_write() will only report success 
				once the complete chunk was written. Once SSL_write() returns with r, 
				r bytes have been successfully written and the next call to SSL_write() 
				must only send the n-r bytes left, imitating the behaviour of write().

  SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER: Make it possible to retry SSL_write() with changed buffer location 
                                       (the buffer contents must stay the same). This is not the default 
				       to avoid the misconception that non-blocking SSL_write() behaves 
				       like non-blocking write(). 

  SSL_MODE_AUTO_RETRY: Never bother the application with retries if the transport is blocking. If a 
                       renegotiation take place during normal operation, a ssl_read(3) or ssl_write(3)
		       would return with -1 and indicate the need to retry with SSL_ERROR_WANT_READ . In 
		       a non-blocking environment applications must be prepared to handle incomplete 
		       read/write operations. In a blocking environment, applications are not always
		       prepared to deal with read/write operations returning without success report. The 
		       flag SSL_MODE_AUTO_RETRY will cause read/write operations to only return after 
		       the handshake and successful completion. 

  The server contains 3 bio objects: bio, abio and out. 'bio' contains the context, 'abio'
  binds to the socket and 'out' is the established connection.
 */
void SSL_Server::bind(){
  SSL_CTX_set_verify(getCTX(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
  SSL_CTX_set_options(getCTX(), SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE);
  SSL_CTX_set_tmp_dh_callback(getCTX(), tmp_dh_callback);
  if(SSL_CTX_set_cipher_list(getCTX(), CIPHER_LIST) != 1)
    msgHandler->error("setting cipher list failed (no valid ciphers)", CRITICAL);

  msgHandler->debug("trying to set context to bio");
  bio = BIO_new_ssl(getCTX(), 0);
  if(bio == NULL){
    string error("Cannot set context to bio ");
    error.append(getSocket());
    error.append("\nSSL_ERROR: ");
    error.append(ERR_reason_error_string(ERR_get_error()));
    msgHandler->error(error, CRITICAL);
  } else
    msgHandler->debug("set context to bio successful");

  BIO_get_ssl(bio, &ssl);
  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

  msgHandler->debug("trying to bind to socket");
  abio = BIO_new_accept((char*)getSocket().c_str());
  BIO_set_accept_bios(abio, bio);

  if(BIO_do_accept(abio) <= 0){
    string error("Bind to socket ");
    error.append(getSocket());
    error.append(" failed.\nSSL_ERROR: ");
    error.append(ERR_reason_error_string(ERR_get_error()));
    msgHandler->error(error, CRITICAL);
  } else
    msgHandler->log("bind to socket successful");
}
Exemple #7
0
static LUA_FUNCTION(openssl_bio_accept)
{
  BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio");
  int first = lua_isnoneornil(L, 2) ? 0 : lua_toboolean(L, 2);
  int ret = BIO_do_accept(bio);
  if (ret == 1)
  {
    if (!first)
    {
      BIO *nb = BIO_pop(bio);

      PUSH_OBJECT(nb, "openssl.bio");
      openssl_newvalue(L, nb);

      lua_pushboolean(L, 1);
      openssl_setvalue(L, nb, "free_all");
      return 1;
    }
    else
      return openssl_pushresult(L, ret);
  }
  else
    luaL_error(L, "BIO_do_accept fail");

  return 0;
}
Exemple #8
0
void *cliserver(void *arg) {

        struct srv_ctx *srv = (struct srv_ctx *)arg;
        struct freeq_ctx *freeqctx = srv->freeqctx;
        struct conn_ctx *conn_ctx;
        int res;
        pthread_t tid;
        BIO *acc, *client;

        static stralloc aggport = {0};

        res = control_readline(&aggport, "control/aggport");
        if (!res)
        {
                err(freeqctx, "unable to read control/aggport");
                exit(FREEQ_ERR);
        }

        stralloc_0(&aggport);

        dbg(freeqctx, "starting aggregation listener on %s\n", (char *)aggport.s);
        acc = BIO_new_accept((char *)aggport.s);
        if (!acc)
        {
                int_error("Error creating server socket");
                exit(FREEQ_ERR);
        }

        if (BIO_do_accept(acc) <= 0)
                int_error("Error binding server socket");

        for (;;)
        {
                dbg(freeqctx, "waiting for connection\n");
                if (BIO_do_accept(acc) <= 0)
                        int_error("Error accepting connection");
                dbg(freeqctx, "accepted connection, setting up ssl\n");

                //bio_peername(acc);

                client = BIO_pop(acc);
                conn_ctx = malloc(sizeof(struct conn_ctx));
                conn_ctx->srvctx = srv;
                conn_ctx->client = client;
                pthread_create(&tid, 0, &conn_handler, (void *)conn_ctx);
        }
}
Exemple #9
0
void *sqlserver(void *arg) {
        struct srv_ctx *srv = (struct srv_ctx *)arg;
        struct freeq_ctx *freeqctx = srv->freeqctx;
        int res;
        pthread_t thread;
        BIO *acc, *client;

        signal(SIGINT, cleanup);
        signal(SIGTERM, cleanup);
        signal(SIGPIPE, SIG_IGN);

        static stralloc sqlport = {0};

        res = control_readline(&sqlport, "control/sqlport");
        if (!res)
        {
                err(freeqctx, "unable to read control/sqlport\n");
                exit(FREEQ_ERR);
        }

        stralloc_0(&sqlport);
        dbg(freeqctx, "starting query listener on %s\n", (char *)sqlport.s);
        acc = BIO_new_accept((char *)sqlport.s);
        if (!acc)
        {
                int_error("Error creating server socket");
                exit(FREEQ_ERR);
        }

        if (BIO_do_accept(acc) <= 0)
                int_error("Error binding server socket");

        for (;;)
        {
                if (BIO_do_accept(acc) <= 0)
                        int_error("Error accepting connection");
                client = BIO_pop(acc);
                struct conn_ctx *conn = malloc(sizeof(struct conn_ctx));
                conn->srvctx = srv;
                conn->client = client;
                pthread_create(&thread, 0, &sqlhandler, (void *)conn);
        }

        BIO_free(acc);
        pthread_exit(FREEQ_OK);;
}
Exemple #10
0
int main(int argc, char * argv[]) {
    BIO * acc, * client;
    THREAD_TYPE tid;
    SSL * ssl;
    SSL_CTX * ctx;

    init_OpenSSL();
    seed_prng();

    ctx = setup_server_ctx();
    
    acc = BIO_new_accept(PORT);
    if (!acc)
        int_error("Error creating server socket");
    if (BIO_do_accept(acc) <= 0)
        int_error("Error binding server socket");
    // BIO_do_accept() will block and wait for a remote connection.
    while (1) {
        if (BIO_do_accept(acc) <= 0)
            int_error("Error accepting connection");
        // get the client BIO
        client = BIO_pop(acc);
        if (!(ssl = SSL_new(ctx)))
            int_error("Error creating SSL context");
        SSL_set_accept_state(ssl);
        SSL_set_bio(ssl, client, client);
        // create a new thread to handle the new connection,
        // The thread will call do_server_loop with the client BIO.
        // THREAD_CREATE(tid, entry, arg);
        // tid is the id of the new thread.
        // server_thread is the function defined above, which will call
        // do_server_loop() with the client BIO.
        THREAD_CREATE(tid, server_thread, ssl);
    }
    SSL_CTX_free(ctx);
    BIO_free(acc);
    return 0;
}
Exemple #11
0
int STS_ServerMain(char **argv) {

    BIO *bio_listen = BIO_new_accept(argv[0]);
    argv++;
    BIO_set_bind_mode(bio_listen, BIO_BIND_REUSEADDR);

    /* First call to BIO_accept() sets up accept BIO */
    if(BIO_do_accept(bio_listen) <= 0) {
        printf("Ошибка при создании сокета\n");
        return 1;
    }

    printf("Ждем подключения клиента.\n");

    /* Wait for incoming connection */
    if(BIO_do_accept(bio_listen) <= 0) {
        printf("Ошибка подключения!\n");
        return 1;
    }
    printf("Соединение установлено.\n");

    return STS_ServerHandleConnection(BIO_pop(bio_listen), argv);
}
Exemple #12
0
int main(int argc, char *argv[])
{
    BIO     *acc, *client;
    SSL     *ssl;
    SSL_CTX *ctx;
    THREAD_TYPE tid;

    init_OpenSSL(  );
    seed_prng();

 
    ctx = setup_server_ctx(  );
 
    acc = BIO_new_accept(PORT);
    if (!acc)
        int_error("Error creating server socket");
 
    if (BIO_do_accept(acc) <= 0)
        int_error("Error binding server socket");
 
    while(1)
    {
        if (BIO_do_accept(acc) <= 0)
            int_error("Error accepting connection");
 
        client = BIO_pop(acc);
        if (!(ssl = SSL_new(ctx)))
        int_error("Error creating SSL context");
        SSL_set_accept_state(ssl);
        SSL_set_bio(ssl, client, client);
        THREAD_CREATE(tid, (void *)server_thread, ssl);
    }
 
    SSL_CTX_free(ctx);
    BIO_free(acc);
    return 0;
}
Exemple #13
0
int main(int argc, char *argv[])
{
	BIO *acc, *client;
	SSL *ssl;
	SSL_CTX *ctx;
	THREAD_TYPE tid;
	void* (*func)(void*) = &server_thread;


	std::cout << "before init\n";
	init_OpenSSL();
	//seed_prng();
	std::cout << "after init\n";

	ctx = setup_server_ctx();

	acc = BIO_new_accept(PORT);
	if(!acc)
		int_error("Error creating socket");
	if(BIO_do_accept(acc) <= 0)
		int_error("Error binding socket");

	for(;;)
	{
		if(BIO_do_accept(acc) <= 0)
			int_error("Error accepting connection");

		client = BIO_pop(acc);
		if(!(ssl = SSL_new(ctx)))
			int_error("Error creating ssl object");
		SSL_set_bio(ssl,client,client);
		THREAD_CREATE(tid,func,ssl);
	}
	BIO_free(acc);
	SSL_CTX_free(ctx);
	return 0;
}
Exemple #14
0
int serverMain(char ** argv) {

    Server server;
    int i;
    
    if (serverReadKey(&server, argv[1])) {
        fprintf(stderr, "Can't read key from file %s!", argv[1]);
        return 1;
    }

    BIO * bio_listen = BIO_new_accept(argv[0]);
    BIO_set_bind_mode(bio_listen, BIO_BIND_REUSEADDR);

    /* First call to BIO_accept() sets up accept BIO */
    if(BIO_do_accept(bio_listen) <= 0) {
        fprintf(stderr, "Error setting up accept\n");
        return 1;
    }

    /* Wait for incoming connection */
    if(BIO_do_accept(bio_listen) <= 0) {
        fprintf(stderr, "Ошибка подключения!\n");
        return 1;
    }
    fprintf(stderr, "Соединение установлено.\n");

    server.conn = BIO_pop(bio_listen);

    if(serverHandleClient(&server)) {
        printf("Клиент не смог доказать знание закрытого ключа RSA!\n\n\n");
    } else {
        printf("Клиент доказал знание закрытого ключа RSA.\n\n\n");
    }
    BIO_free(server.conn);
    BIO_free(bio_listen);
    return 0;
}
/*
  The server goes into the listening mode (BIO_do_accept(abio)).
  If an incoming connection appears it will be passed to a
  ConnectionHandler. For this the bio object 'out' pops the first
  bio from 'abio' (the latest connection).
 */
void SSL_Server::listen(){
  msgHandler->log("entering listening mode now");
  while(true){
    if(BIO_do_accept(abio) <= 0){
      string error("Entering listening mode failed.\nSSL_ERROR: ");
      error.append(ERR_reason_error_string(ERR_get_error()));
      msgHandler->error(error, CRITICAL);
    }
    out = BIO_pop(abio);
    
    msgHandler->log("incoming connection");
    connHandler->addConnection(out);
    msgHandler->log("entering listening mode again.");
  }
}
Exemple #16
0
/** Thread body.  Accepts SSL connections and adds peers as they connect */
wxThread::ExitCode RAIN::ConnectionListener::Entry()
{
	BIO *listener, *client;
	SSL *client_ssl;
	SSL_CTX* ssl_ctx = globalCredentialManager->GetSSLContext();

	wxLogVerbose(wxT("starting up RAIN::ConnectionListener; ssl_ctx = %08x"), ssl_ctx);

	listener = BIO_new_accept(DEFAULT_ACCEPT_STR);

	if (!listener)
	{
		wxLogError("Server socket creation failed");
		return NULL;
	}

	/* set listener to be non blocking - needed for
	 * this thread's proper behaviour with timely exiting 
	 * 
	 * also set BIO_BIND_REUSEADDR */
	// broken in gcc severely
	const char a[] = "a";
	BIO_ctrl(listener, BIO_C_SET_ACCEPT, 1, (void*)a);
	BIO_set_bind_mode(listener, BIO_BIND_REUSEADDR);

	// now bind the port
	if (BIO_do_accept(listener) <= 0)
	{
		wxLogError("Server socket binding failed");
		BIO_free_all(listener);
		return NULL;
	}

	while (true)
	{
		if (this->GetThread()->TestDestroy())
		{
			wxLogVerbose("RAIN::ConnectionListener thread finishing");
			BIO_free_all(listener);
			return NULL;
		} else {
			//wxLogVerbose("RAIN::ConnectionListener thread continuing");
		}

		if (BIO_do_accept(listener) > 0)
		{
			// there's a connection waiting to be accepted
			client = BIO_pop(listener);

			if (!(client_ssl = SSL_new(ssl_ctx)))
			{
				wxLogFatalError("RAIN::ConnectionListener - Error creating new SSL connection from context");
				BIO_free_all(client);
				BIO_free_all(listener);
				return NULL;
			} else {
				SSL_set_bio(client_ssl, client, client);

				int sa_ret = SSL_accept(client_ssl);
				int SSLge = SSL_get_error(client_ssl, sa_ret);
				int runawayGuard = 15;

				while (runawayGuard-- && sa_ret == -1 && (SSLge == SSL_ERROR_SSL || SSLge == SSL_ERROR_WANT_READ || SSLge == SSL_ERROR_WANT_WRITE))
				{
					/* the handshaking occurs in a non-blocking way, the underlying bio 'client'
					 * inherits the listener's non-blockingness */
					sa_ret = SSL_accept(client_ssl);
					SSLge = SSL_get_error(client_ssl, sa_ret);
					wxThread::Sleep(1000);
				}

				if (runawayGuard < 1 || sa_ret <= 0)
				{
					SSL_free(client_ssl);

					if (runawayGuard < 1)
						wxLogError("RAIN::ConnectionListener - Timeout while handshaking for new SSL connection");
					else
						wxLogError("RAIN::ConnectionListener - Error accepting new SSL connection: ssl_accept returned %d; ssl_get_error returned %d", sa_ret, SSLge);
				} else {
					wxLogVerbose("RAIN::ConnectionListener - SSL_accept succeeded");

					RAIN::Connection *nc = new RAIN::Connection(client_ssl);
					this->connectionPool->AddServedPeer(nc);
				}
			}
		}

		wxThread::Sleep(2000);
	}
}
Exemple #17
0
int main(int argc, char *argv[])
{
    char *port = "*:4433";
    BIO *ssl_bio, *tmp;
    SSL_CTX *ctx;
    SSL_CONF_CTX *cctx;
    char buf[512];
    BIO *in = NULL;
    int ret = 1, i;
    char **args = argv + 1;
    int nargs = argc - 1;

    SSL_load_error_strings();

    /* Add ciphers and message digests */
    OpenSSL_add_ssl_algorithms();

    ctx = SSL_CTX_new(SSLv23_server_method());

    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
    while (*args && **args == '-') {
        int rv;
        /* Parse standard arguments */
        rv = SSL_CONF_cmd_argv(cctx, &nargs, &args);
        if (rv == -3) {
            fprintf(stderr, "Missing argument for %s\n", *args);
            goto err;
        }
        if (rv < 0) {
            fprintf(stderr, "Error in command %s\n", *args);
            ERR_print_errors_fp(stderr);
            goto err;
        }
        /* If rv > 0 we processed something so proceed to next arg */
        if (rv > 0)
            continue;
        /* Otherwise application specific argument processing */
        if (strcmp(*args, "-port") == 0) {
            port = args[1];
            if (port == NULL) {
                fprintf(stderr, "Missing -port argument\n");
                goto err;
            }
            args += 2;
            nargs -= 2;
            continue;
        } else {
            fprintf(stderr, "Unknown argument %s\n", *args);
            goto err;
        }
    }

    if (!SSL_CONF_CTX_finish(cctx)) {
        fprintf(stderr, "Finish error\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }
#ifdef ITERATE_CERTS
    /*
     * Demo of how to iterate over all certificates in an SSL_CTX structure.
     */
    {
        X509 *x;
        int rv;
        rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST);
        while (rv) {
            X509 *x = SSL_CTX_get0_certificate(ctx);
            X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0,
                                  XN_FLAG_ONELINE);
            printf("\n");
            rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT);
        }
        fflush(stdout);
    }
#endif
    /* Setup server side SSL bio */
    ssl_bio = BIO_new_ssl(ctx, 0);

    if ((in = BIO_new_accept(port)) == NULL)
        goto err;

    /*
     * This means that when a new connection is accepted on 'in', The ssl_bio
     * will be 'duplicated' and have the new socket BIO push into it.
     * Basically it means the SSL BIO will be automatically setup
     */
    BIO_set_accept_bios(in, ssl_bio);

 again:
    /*
     * The first call will setup the accept socket, and the second will get a
     * socket.  In this loop, the first actual accept will occur in the
     * BIO_read() function.
     */

    if (BIO_do_accept(in) <= 0)
        goto err;

    for (;;) {
        i = BIO_read(in, buf, 512);
        if (i == 0) {
            /*
             * If we have finished, remove the underlying BIO stack so the
             * next time we call any function for this BIO, it will attempt
             * to do an accept
             */
            printf("Done\n");
            tmp = BIO_pop(in);
            BIO_free_all(tmp);
            goto again;
        }
        if (i < 0)
            goto err;
        fwrite(buf, 1, i, stdout);
        fflush(stdout);
    }

    ret = 0;
 err:
    if (ret) {
        ERR_print_errors_fp(stderr);
    }
    BIO_free(in);
    exit(ret);
    return (!ret);
}
Exemple #18
0
int main(){
  int len = 1024; //buffer length
  char buf[len]; //read buffer
  
  /* Initializing OpenSSL */
  SSL_load_error_strings();
  ERR_load_BIO_strings();
  OpenSSL_add_all_algorithms();
  SSL_library_init();

  BIO *bio, *abio, *out; //the sockets
  SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
  SSL *ssl;

  if( ctx == NULL ){
    fprintf(stderr, "DEBUG ctx is null\n");
    fprintf(stderr, "ERROR::OpenSLL: %s\n", ERR_reason_error_string(ERR_get_error()));
    exit(1);
  }
  
  //get password for private key
  //  SSL_CTX_set_default_passwd_cb( ctx, &pem_passwd_cb );

  //load certificate (with public key)
  SSL_CTX_use_certificate_file( ctx, "/home/mml/Develop/ca/certs/01.pem", SSL_FILETYPE_PEM);
  //load private key
  SSL_CTX_use_PrivateKey_file( ctx, "/home/mml/Develop/ca/testkey.pem", SSL_FILETYPE_PEM);

  bio = BIO_new_ssl(ctx, 0);
  if( bio == NULL ){
    fprintf(stderr, "ERROR cannot bind\n");
    exit(1);
  }

  BIO_get_ssl(bio, &ssl);
  SSL_set_mode( ssl, SSL_MODE_AUTO_RETRY );

  abio = BIO_new_accept("localhost:15001");
  BIO_set_accept_bios(abio, bio);

  BIO_do_accept(abio);

  fprintf(stdout, "DEBUG: waiting for connection\n");
  BIO_do_accept(abio);

  out = BIO_pop(abio);

  fprintf(stdout, "DEBUG: doing handshake\n");
  BIO_do_handshake(out);
  
  if(BIO_write(out, "Hello", 5) <= 0){
    if(! BIO_should_retry(bio)) {
      fprintf(stderr, "ERROR connection is already closed. (write)\n");
      exit(1);
    } else {
      //retry routine
    }
  }
  
  bzero(buf, len); 
  if( BIO_read(out, buf, len) <= 0 ){
    if( !(BIO_should_retry(bio)) ){
      fprintf(stderr, "ERROR connection is already closed (read)\n");
      exit(0);
      
    } else {
      //retry routine
    }
  }

  fprintf(stdout, "Hello%s\n", buf);

  //close connection
  BIO_free_all(abio);
  BIO_free_all(out);
  BIO_free_all(bio);
  SSL_CTX_free(ctx);
  
  return 0;
}
Exemple #19
0
/*
 * This starts a minimal TLS server that only does a
 * handshake and then closes the connection.  This is
 * strictly used to test TLS session negotiation
 * behavior with EST.
 */
static void us1060_start_tls_server (char *cipherstring)
{
    BIO *conn;
    BIO *listener;
    BIO *berr;
    char h_p[25];
    SSL *ssl;
    SSL_CTX *ssl_ctx = NULL;
    int nid, rv;
    EC_KEY *ecdh = NULL;

    berr = BIO_new_fp(stderr, BIO_NOCLOSE);

    ssl_ctx = SSL_CTX_new(SSLv23_server_method());
    if (!ssl_ctx) {
	printf("Failed to create SSL context\n");
	ERR_print_errors(berr);
	return;
    }

    SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);

    if (SSL_CTX_use_certificate_chain_file(ssl_ctx, US1060_RSA_CERT) != 1) {
	printf("Failed to load server certificate\n");
	ERR_print_errors(berr);
	return;
    }
    if (SSL_CTX_use_PrivateKey_file(ssl_ctx, US1060_RSA_KEY, SSL_FILETYPE_PEM) != 1) {
	printf("Failed to load server private key\n");
	ERR_print_errors(berr);
	return;
    }

    SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 |
	                         SSL_OP_NO_SSLv3 |
				 SSL_OP_NO_TLSv1 |
                                 SSL_OP_SINGLE_ECDH_USE | 
				 SSL_OP_SINGLE_DH_USE |
			         SSL_OP_NO_TICKET);

    nid = OBJ_sn2nid("prime256v1");
    ecdh = EC_KEY_new_by_curve_name(nid);
    if (ecdh == NULL) {
	printf("Failed to retreive ECDH curve\n");
	ERR_print_errors(berr);
	return;
    }
    SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
    EC_KEY_free(ecdh);

    if (SSL_CTX_set_cipher_list(ssl_ctx, cipherstring) != 1) {
	printf("Failed to set server cipher list\n");
	ERR_print_errors(berr);
	return;
    }
    SSL_CTX_set_srp_username_callback(ssl_ctx, us1060_srp_cb);

    sprintf(h_p, "%s:%d", US1060_SERVER_IP, US1060_TLS_PORT);
    listener = BIO_new_accept(h_p);
    if (listener == NULL) {
	printf("IP connection failed\n");
	return;
    }
    BIO_set_bind_mode(listener, BIO_BIND_REUSEADDR);

    /*
     * The first call to do_accept binds the socket
     */
    if (BIO_do_accept(listener) <= 0) {
	printf("TCP bind failed\n");
	BIO_free_all(listener);
	return;
    }

    /*
     * The second call to do_accept waits for a new
     * connection request on the listener.
     * Note that we are in blocking mode for this socket
     */
    if (BIO_do_accept(listener) <= 0) {
	printf("TCP accept failed\n");
	BIO_free_all(listener);
	return;
    }
    conn = BIO_pop(listener);

    ssl = SSL_new(ssl_ctx);
    SSL_set_bio(ssl, conn, conn);
    /*
     * Now that we have everything ready, let's start waiting for
     * a client to contact us.  Normally we might using a pthread
     * or some other construct to avoid blocking on the main 
     * thread while waiting for an incoming connection.  This
     * code is simply a contrived example, we will wait on the
     * main thread for an incoming connection.
     */
    rv = SSL_accept(ssl);
    if (rv <= 0) {
	printf("\nFailed to complete TLS handshake %d\n", rv);
	ERR_print_errors(berr);
    }
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ssl_ctx);
    BIO_free(berr);
    (void)BIO_reset(listener);
    BIO_free_all(listener);
    pthread_exit(0);
}
Exemple #20
0
int main(int argc, char **argv)
{
  char buf[BUFFER_SIZE];

  SSL_CTX *ctx;
  const SSL_METHOD *method;
  BIO *abio, *cbio;

  if (argc < 2) {
    fprintf(stderr, "Usage: %s [port]\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  // init openssl lib.
  SSL_library_init(); // call OpenSSL_add_ssl_algorithms();
  ERR_load_BIO_strings();
  SSL_load_error_strings();

  // setup tls context.
  method = TLSv1_2_server_method(); // SSLv23_server_method();
  ctx = SSL_CTX_new(method);
  if (!ctx) {
    perror("Unable to create SSL context");
    ERR_print_errors_fp(stderr);
    exit(EXIT_FAILURE);
  }
  /* Set the key and cert */
  if (SSL_CTX_use_certificate_file(ctx, CERT_FILE_PATH, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(EXIT_FAILURE);
  }
  if (SSL_CTX_use_PrivateKey_file(ctx, KEY_FILE_PATH, SSL_FILETYPE_PEM) <= 0 ) {
    ERR_print_errors_fp(stderr);
    exit(EXIT_FAILURE);
  }
  SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384");
  SSL_CTX_set_ecdh_auto(ctx, 1);

  // create BIO(high level API); for accept
  abio = BIO_new_accept(argv[1]);
  if(BIO_do_accept(abio) <= 0) {
    // first BIO_do_accept() is as to init BIO.
    fprintf(stderr, "Error setting up accept\n");
    ERR_print_errors_fp(stderr);
    exit(0);
  }
  // configuration for I/O operation over ssl/tls.
  BIO_set_accept_bios(abio, BIO_new_ssl(ctx, 0));

  // listen loop
  printf("Server is listening on %d\n", atoi(argv[1]));
  while (1) {
    if(BIO_do_accept(abio) <= 0) {
      fprintf(stderr, "Error accepting connection\n");
      ERR_print_errors_fp(stderr);
      exit(0);
    }
    fprintf(stderr, "Connection 1 established\n");
    /* Retrieve BIO for connection */
    cbio = BIO_pop(abio);
    while (1) {
      int len, err;
      len = BIO_read(cbio, buf, BUFFER_SIZE);
      if (!len) break;
      if (len < 0) {
        fprintf(stderr, "error SSL_read");
        break;
      }
      err = BIO_write(cbio, buf, len);
      if (err < 0) {
        fprintf(stderr, "error SSL_write");
        break;
      }
    }
    BIO_free(cbio);
  }
}
Exemple #21
0
bool TLS_SOCKET_CLASS::accept(BASE_SOCKET_CLASS** acceptedSocket_ptr_ptr)

//  DESCRIPTION     : Accept connection from listen socket.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : The returned socket was new'ed so it must be deleted by the caller
//<<===========================================================================
{
	*acceptedSocket_ptr_ptr = NULL;
	BIO* acceptedBio_ptr;
	SSL* acceptedSsl_ptr;
	long error;
	int fileDesc;
	struct fd_set fds;
	struct timeval tv = {1, 0}; // always timeout in 1 second
	int sel;

	if (terminatingM)
	{
		if (loggerM_ptr) 
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - In process of terminating.  Cannot accept.");
		}

		// return - in process of termintating
		return false;
	}

	// make sure we are listening to the port
	if (!listeningM)
	{
		if (loggerM_ptr)
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Socket is not listening to port %d.  Cannot accept a connection.", 
				localListenPortM);
		}
		return false;
	}
	if (acceptBioM_ptr == NULL)
	{
		if (loggerM_ptr)
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Socket is listening to port %d, but not bound.", 
				localListenPortM);
		}
		listeningM = false;
		return false;
	}

	if (loggerM_ptr) 
	{
		loggerM_ptr->text(LOG_DEBUG, 1, "Secure Socket - tls::accept()");
	}

	// get the file descriptor and set up the file descriptor set for select()
	fileDesc = BIO_get_fd(acceptBioM_ptr, NULL);
	if (fileDesc == -1)
	{
		openSslError("getting listen socket file descriptor");
		return false;
	}

	// wait for a connection
	do
	{
		FD_ZERO(&fds);
		FD_SET(fileDesc, &fds);

		sel = select(fileDesc + 1, &fds, NULL, NULL, &tv);
		if (sel == 0)
		{
			// no data at the end of the timeout - check for terminating
			if (terminatingM)
			{
				return false;
			}
		}
		else if (sel == SOCKET_ERROR)
		{
			// socket error
			if (loggerM_ptr)
			{
				loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Error waiting to accept connection (error code %d)", WSAGetLastError());
			}
			return false;
		}
		else if (sel != 1)
		{
			// unknown error
			if (loggerM_ptr)
			{
				loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Unknown error while waiting to accept connection (select returned %d)", sel);
			}
			return false;
		}

	} while (sel != 1);

	// accept a connection
	if (BIO_do_accept(acceptBioM_ptr) <= 0)
	{
		openSslError(LOG_DEBUG, "accepting connection on port %d", localListenPortM);
		close();
		return false;
	}

	// get the new connection
	acceptedBio_ptr = BIO_pop(acceptBioM_ptr);

	// setup the socket structure
	acceptedSsl_ptr = SSL_new(ctxM_ptr);
	if (acceptedSsl_ptr == NULL)
	{
		openSslError("creating accepted secure socket object");
		BIO_free(acceptedBio_ptr);
		return false;
	}

	// set the 'this' pointer for the callbacks openSslMsgCallback and openSslVerifyCallback
	SSL_set_msg_callback_arg(acceptedSsl_ptr, static_cast<void*>(this));

	SSL_set_accept_state(acceptedSsl_ptr);
	SSL_set_bio(acceptedSsl_ptr, acceptedBio_ptr, acceptedBio_ptr); // the ssl takes over the BIO memory
	if (SSL_accept(acceptedSsl_ptr) <= 0)
	{
		openSslError("accepting secure connection to port %d", localListenPortM);
		SSL_free(acceptedSsl_ptr);
		return false;
	}

	// make sure everything is OK
	error = postConnectionCheck(acceptedSsl_ptr);
	if (error != X509_V_OK)
	{
		openSslError("checking connection parameters after accepting from port %d", localListenPortM);
		SSL_free(acceptedSsl_ptr);
		return false;
	}

	// create a socket for the new connection
	*acceptedSocket_ptr_ptr = new TLS_SOCKET_CLASS(*this, acceptedSsl_ptr);

	if (loggerM_ptr && (loggerM_ptr->getLogMask() & LOG_DEBUG))
	{
		char buffer[128];

		SSL_CIPHER_description(SSL_get_current_cipher(acceptedSsl_ptr), buffer, 128);
		loggerM_ptr->text(LOG_DEBUG, 1, "Secure Socket - %s connection opened using cipher %s",
			SSL_get_version(acceptedSsl_ptr), buffer);
	}

	return true;
}
Exemple #22
0
int main(int argc, char *argv[])
{
    char *port = "*:4433";
    BIO *in = NULL;
    BIO *ssl_bio, *tmp;
    SSL_CTX *ctx;
    SSL_CONF_CTX *cctx = NULL;
    CONF *conf = NULL;
    STACK_OF(CONF_VALUE) *sect = NULL;
    CONF_VALUE *cnf;
    long errline = -1;
    char buf[512];
    int ret = EXIT_FAILURE, i;

    ctx = SSL_CTX_new(TLS_server_method());

    conf = NCONF_new(NULL);

    if (NCONF_load(conf, "accept.cnf", &errline) <= 0) {
        if (errline <= 0)
            fprintf(stderr, "Error processing config file\n");
        else
            fprintf(stderr, "Error on line %ld\n", errline);
        goto err;
    }

    sect = NCONF_get_section(conf, "default");

    if (sect == NULL) {
        fprintf(stderr, "Error retrieving default section\n");
        goto err;
    }

    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
    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++) {
        int rv;
        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 err;
        }
        if (strcmp(cnf->name, "Port") == 0) {
            port = cnf->value;
        } else {
            fprintf(stderr, "Unknown configuration option %s\n", cnf->name);
            goto err;
        }
    }

    if (!SSL_CONF_CTX_finish(cctx)) {
        fprintf(stderr, "Finish error\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }

    /* Setup server side SSL bio */
    ssl_bio = BIO_new_ssl(ctx, 0);

    if ((in = BIO_new_accept(port)) == NULL)
        goto err;

    /*
     * This means that when a new connection is accepted on 'in', The ssl_bio
     * will be 'duplicated' and have the new socket BIO push into it.
     * Basically it means the SSL BIO will be automatically setup
     */
    BIO_set_accept_bios(in, ssl_bio);

 again:
    /*
     * The first call will setup the accept socket, and the second will get a
     * socket.  In this loop, the first actual accept will occur in the
     * BIO_read() function.
     */

    if (BIO_do_accept(in) <= 0)
        goto err;

    for (;;) {
        i = BIO_read(in, buf, 512);
        if (i == 0) {
            /*
             * If we have finished, remove the underlying BIO stack so the
             * next time we call any function for this BIO, it will attempt
             * to do an accept
             */
            printf("Done\n");
            tmp = BIO_pop(in);
            BIO_free_all(tmp);
            goto again;
        }
        if (i < 0) {
            if (BIO_should_retry(in))
                continue;
            goto err;
        }
        fwrite(buf, 1, i, stdout);
        fflush(stdout);
    }

    ret = EXIT_SUCCESS;
 err:
    if (ret != EXIT_SUCCESS)
        ERR_print_errors_fp(stderr);
    BIO_free(in);
    return ret;
}
netsnmp_transport *
netsnmp_tlstcp_open(netsnmp_transport *t)
{
    _netsnmpTLSBaseData *tlsdata;
    BIO *bio;
    SSL_CTX *ctx;
    SSL *ssl;
    int rc = 0;
    _netsnmp_verify_info *verify_info;

    netsnmp_assert_or_return(t != NULL, NULL);
    netsnmp_assert_or_return(t->data != NULL, NULL);
    netsnmp_assert_or_return(sizeof(_netsnmpTLSBaseData) == t->data_length,
                             NULL);

    tlsdata = t->data;

    if (tlsdata->flags & NETSNMP_TLSBASE_IS_CLIENT) {
        /* Is the client */

        /* RFC5953 Section 5.3.1:  Establishing a Session as a Client
         *    1)  The snmpTlstmSessionOpens counter is incremented.
         */
        snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENS);

        /* RFC5953 Section 5.3.1:  Establishing a Session as a Client
          2)  The client selects the appropriate certificate and cipher_suites
              for the key agreement based on the tmSecurityName and the
              tmRequestedSecurityLevel for the session.  For sessions being
              established as a result of a SNMP-TARGET-MIB based operation, the
              certificate will potentially have been identified via the
              snmpTlstmParamsTable mapping and the cipher_suites will have to
              be taken from system-wide or implementation-specific
              configuration.  If no row in the snmpTlstmParamsTable exists then
              implementations MAY choose to establish the connection using a
              default client certificate available to the application.
              Otherwise, the certificate and appropriate cipher_suites will
              need to be passed to the openSession() ASI as supplemental
              information or configured through an implementation-dependent
              mechanism.  It is also implementation-dependent and possibly
              policy-dependent how tmRequestedSecurityLevel will be used to
              influence the security capabilities provided by the (D)TLS
              connection.  However this is done, the security capabilities
              provided by (D)TLS MUST be at least as high as the level of
              security indicated by the tmRequestedSecurityLevel parameter.
              The actual security level of the session is reported in the
              tmStateReference cache as tmSecurityLevel.  For (D)TLS to provide
              strong authentication, each principal acting as a command
              generator SHOULD have its own certificate.
        */
        /*
          Implementation notes: we do most of this in the
          sslctx_client_setup The transport should have been
          f_config()ed with the proper fingerprints to use (which is
          stored in tlsdata), or we'll use the default identity
          fingerprint if that can be found.
        */

        /* XXX: check securityLevel and ensure no NULL fingerprints are used */

        /* set up the needed SSL context */
        tlsdata->ssl_context = ctx =
                                   sslctx_client_setup(TLSv1_method(), tlsdata);
        if (!ctx) {
            snmp_log(LOG_ERR, "failed to create TLS context\n");
            return NULL;
        }

        /* RFC5953 Section 5.3.1:  Establishing a Session as a Client
           3)  Using the destTransportDomain and destTransportAddress values,
               the client will initiate the (D)TLS handshake protocol to
               establish session keys for message integrity and encryption.
        */
        /* Implementation note:
           The transport domain and address are pre-processed by this point
        */

        /* Create a BIO connection for it */
        DEBUGMSGTL(("tlstcp", "connecting to tlstcp %s\n",
                    tlsdata->addr_string));
        t->remote = (void *) strdup(tlsdata->addr_string);
        t->remote_length = strlen(tlsdata->addr_string) + 1;

        bio = BIO_new_connect(tlsdata->addr_string);

        /* RFC5953 Section 5.3.1:  Establishing a Session as a Client
           3) continued:
              If the attempt to establish a session is unsuccessful, then
              snmpTlstmSessionOpenErrors is incremented, an error indication is
              returned, and processing stops.
        */

        if (NULL == bio) {
            snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS);
            snmp_log(LOG_ERR, "tlstcp: failed to create bio\n");
            _openssl_log_error(rc, NULL, "BIO creation");
            return NULL;
        }


        /* Tell the BIO to actually do the connection */
        if ((rc = BIO_do_connect(bio)) <= 0) {
            snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS);
            snmp_log(LOG_ERR, "tlstcp: failed to connect to %s\n",
                     tlsdata->addr_string);
            _openssl_log_error(rc, NULL, "BIO_do_connect");
            BIO_free(bio);
            return NULL;
        }

        /* Create the SSL layer on top of the socket bio */
        ssl = tlsdata->ssl = SSL_new(ctx);
        if (NULL == ssl) {
            snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS);
            snmp_log(LOG_ERR, "tlstcp: failed to create a SSL connection\n");
            BIO_free(bio);
            return NULL;
        }

        /* Bind the SSL layer to the BIO */
        SSL_set_bio(ssl, bio, bio);
        SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

        verify_info = SNMP_MALLOC_TYPEDEF(_netsnmp_verify_info);
        if (NULL == verify_info) {
            snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS);
            snmp_log(LOG_ERR, "tlstcp: failed to create a SSL connection\n");
            SSL_shutdown(ssl);
            BIO_free(bio);
            return NULL;
        }

        SSL_set_ex_data(ssl, tls_get_verify_info_index(), verify_info);

        /* Then have SSL do it's connection over the BIO */
        if ((rc = SSL_connect(ssl)) <= 0) {
            snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS);
            snmp_log(LOG_ERR, "tlstcp: failed to ssl_connect\n");
            BIO_free(bio);
            return NULL;
        }

        /* RFC5953 Section 5.3.1: Establishing a Session as a Client
           3) continued:
              If the session failed to open because the presented
              server certificate was unknown or invalid then the
              snmpTlstmSessionUnknownServerCertificate or
              snmpTlstmSessionInvalidServerCertificates MUST be
              incremented and a snmpTlstmServerCertificateUnknown or
              snmpTlstmServerInvalidCertificate notification SHOULD be
              sent as appropriate.  Reasons for server certificate
              invalidation includes, but is not limited to,
              cryptographic validation failures and an unexpected
              presented certificate identity.
        */

        /* RFC5953 Section 5.3.1: Establishing a Session as a Client
           4)  The (D)TLS client MUST then verify that the (D)TLS server's
               presented certificate is the expected certificate.  The (D)TLS
               client MUST NOT transmit SNMP messages until the server
               certificate has been authenticated, the client certificate has
               been transmitted and the TLS connection has been fully
               established.

               If the connection is being established from configuration based
               on SNMP-TARGET-MIB configuration, then the snmpTlstmAddrTable
               DESCRIPTION clause describes how the verification is done (using
               either a certificate fingerprint, or an identity authenticated
               via certification path validation).

               If the connection is being established for reasons other than
               configuration found in the SNMP-TARGET-MIB then configuration and
               procedures outside the scope of this document should be followed.
               Configuration mechanisms SHOULD be similar in nature to those
               defined in the snmpTlstmAddrTable to ensure consistency across
               management configuration systems.  For example, a command-line
               tool for generating SNMP GETs might support specifying either the
               server's certificate fingerprint or the expected host name as a
               command line argument.
        */

        /* Implementation notes:
           - All remote certificate fingerprints are expected to be
             stored in the transport's config information.  This is
             true both for CLI clients and TARGET-MIB sessions.
           - netsnmp_tlsbase_verify_server_cert implements these checks
        */
        if (netsnmp_tlsbase_verify_server_cert(ssl, tlsdata) != SNMPERR_SUCCESS) {
            /* XXX: unknown vs invalid; two counters */
            snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONUNKNOWNSERVERCERTIFICATE);
            snmp_log(LOG_ERR, "tlstcp: failed to verify ssl certificate\n");
            SSL_shutdown(ssl);
            BIO_free(bio);
            return NULL;
        }

        /* RFC5953 Section 5.3.1: Establishing a Session as a Client
           5)  (D)TLS provides assurance that the authenticated identity has
               been signed by a trusted configured certification authority.  If
               verification of the server's certificate fails in any way (for
               example because of failures in cryptographic verification or the
               presented identity did not match the expected named entity) then
               the session establishment MUST fail, the
               snmpTlstmSessionInvalidServerCertificates object is incremented.
               If the session can not be opened for any reason at all, including
               cryptographic verification failures, then the
               snmpTlstmSessionOpenErrors counter is incremented and processing
               stops.

        */
        /* XXX: add snmpTlstmSessionInvalidServerCertificates on
           crypto failure */

        /* RFC5953 Section 5.3.1: Establishing a Session as a Client
           6)  The TLSTM-specific session identifier (tlstmSessionID) is set in
           the tmSessionID of the tmStateReference passed to the TLS
           Transport Model to indicate that the session has been established
           successfully and to point to a specific (D)TLS connection for
           future use.  The tlstmSessionID is also stored in the LCD for
           later lookup during processing of incoming messages
           (Section 5.1.2).
        */
        /* Implementation notes:
           - the tlsdata pointer is used as our session identifier, as
             noted in the netsnmp_tlstcp_recv() function comments.
        */

        t->sock = BIO_get_fd(bio, NULL);

    } else {
#ifndef NETSNMP_NO_LISTEN_SUPPORT
        /* Is the server */

        /* Create the socket bio */
        DEBUGMSGTL(("tlstcp", "listening on tlstcp port %s\n",
                    tlsdata->addr_string));
        tlsdata->accept_bio = BIO_new_accept(tlsdata->addr_string);
        t->local = (void *) strdup(tlsdata->addr_string);
        t->local_length = strlen(tlsdata->addr_string)+1;
        if (NULL == tlsdata->accept_bio) {
            snmp_log(LOG_ERR, "TLSTCP: Falied to create a accept BIO\n");
            return NULL;
        }

        /* openssl requires an initial accept to bind() the socket */
        if (BIO_do_accept(tlsdata->accept_bio) <= 0) {
            _openssl_log_error(rc, tlsdata->ssl, "BIO_do__accept");
            snmp_log(LOG_ERR, "TLSTCP: Falied to do first accept on the TLS accept BIO\n");
            return NULL;
        }

        /* create the OpenSSL TLS context */
        tlsdata->ssl_context =
            sslctx_server_setup(TLSv1_method());

        t->sock = BIO_get_fd(tlsdata->accept_bio, NULL);
        t->flags |= NETSNMP_TRANSPORT_FLAG_LISTEN;
#else /* NETSNMP_NO_LISTEN_SUPPORT */
        return NULL;
#endif /* NETSNMP_NO_LISTEN_SUPPORT */
    }
    return t;
}
Exemple #24
0
int main(int argc, char *argv[])
{
	SSL *ssl;
	SSL_CTX *ctx;
	BIO *bio, *abio, *cbio;
	pthread_t t;
	X509 *peer;
	int (*callback)(char *, int, int, void *) = &password_callback;

	SSL_library_init();

	SSL_load_error_strings();
	ERR_load_BIO_strings();
	ERR_load_SSL_strings();

	printf("Attempting to create SSL context...\n");
	ctx = SSL_CTX_new(SSLv3_server_method());
	if(ctx == NULL) {
		printf("Failed. Aborting.\n");
		ERR_print_errors_fp(stdout);
		return 0;
	}

	printf("Loading certificates...\n");
	SSL_CTX_set_default_passwd_cb(ctx, callback);
	//if (SSL_CTX_use_certificate_file(ctx, "./CA/server_cert.pem", SSL_FILETYPE_PEM) != 1) {
	if (SSL_CTX_use_certificate_chain_file(ctx, "./CAtest/server_cert.pem") != 1) {
		/* Handle failed load here */
		ERR_print_errors_fp(stdout);
		exit(1);
	}
	if (SSL_CTX_use_PrivateKey_file(ctx, "./CAtest/private/server_key.pem", SSL_FILETYPE_PEM) != 1) {
		/* Handle failed load here */
		ERR_print_errors_fp(stdout);
		exit(1);
	}
	if (!SSL_CTX_load_verify_locations(ctx, "./CAtest/cacert.pem", "./CA/")) {
		/* Handle failed load here */
        ERR_print_errors_fp(stdout);
		exit(1);
	}

	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, verify_callback);
	SSL_CTX_set_verify_depth(ctx, 5);

	printf("Attempting to create BIO object...\n");
	bio = BIO_new_ssl(ctx, 0);
	if(bio == NULL) {
		printf("Failed. Aborting.\n");
		ERR_print_errors_fp(stdout);
		SSL_CTX_free(ctx);
		return 0;
	}

	printf("Attempting to set up BIO for SSL...\n");
	BIO_get_ssl(bio, &ssl);
	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

	abio = BIO_new_accept("4422");
	BIO_set_accept_bios(abio, bio);

	/* First call to BIO_accept() sets up accept BIO */
	if (BIO_do_accept(abio) <= 0) {
		fprintf(stderr, "Error setting up accept\n");
		ERR_print_errors_fp(stderr);
		exit(0);
	}

	do {
		/* Wait for incoming connection */
		if (BIO_do_accept(abio) <= 0) {
			fprintf(stderr, "Error accepting connection\n");
			ERR_print_errors_fp(stderr);
			exit(0);
		}

		fprintf(stderr, "Connection 1 established\n");
		/* Retrieve BIO for connection */
		cbio = BIO_pop(abio);
		pthread_create(&t, NULL, handle_connection, cbio);
	} while (1);

	SSL_shutdown(ssl);
	BIO_free_all(bio);
	BIO_free_all(abio);
	SSL_CTX_free(ctx);
	SSL_free(ssl);

	return 0;
}
void *phr_authority_list_loading_main(void *arg)
{
	BIO         *bio_acc    = NULL;
	BIO         *bio_client = NULL;
    	SSL         *ssl_client = NULL;
    	SSL_CTX     *ctx        = NULL;

	int         err;
	char        *hosts[2];

    	ctx = setup_server_ctx(ESA_CERTFILE_PATH, ESA_CERTFILE_PASSWD, EMU_ROOT_CA_ONLY_CERT_CERTFILE_PATH);
    	bio_acc = BIO_new_accept(ESA_PHR_AUTHORITY_LIST_LOADING_PORT);
    	if(!bio_acc)
        	int_error("Creating server socket failed");
  
    	if(BIO_do_accept(bio_acc) <= 0)
        	int_error("Binding server socket failed");
  
    	for(;;)
    	{
        	if(BIO_do_accept(bio_acc) <= 0)
            		int_error("Accepting connection failed");
 
        	bio_client = BIO_pop(bio_acc);

        	if(!(ssl_client = SSL_new(ctx)))
            		int_error("Creating SSL context failed");

        	SSL_set_bio(ssl_client, bio_client, bio_client);
		if(SSL_accept(ssl_client) <= 0)
		{
        		fprintf(stderr, "Accepting SSL connection failed\n");
			goto ERROR_AT_SSL_LAYER;
		}

		hosts[0] = ADMIN_CN; 
		hosts[1] = USER_CN; 
    		if((err = post_connection_check(ssl_client, hosts, 2, true, GLOBAL_authority_name)) != X509_V_OK)
    		{
        		fprintf(stderr, "Checking peer certificate failed\n\"%s\"\n", X509_verify_cert_error_string(err));
        		goto ERROR_AT_SSL_LAYER;
    		}

		// Serve the PHR authority list
		if(!load_phr_authority_list(ssl_client))
			goto ERROR_AT_SSL_LAYER;
		
ERROR_AT_SSL_LAYER:

		SSL_cleanup(ssl_client);
		ssl_client = NULL;
    		ERR_remove_state(0);
    	}
    
    	SSL_CTX_free(ctx);
	ctx = NULL;

    	BIO_free(bio_acc);
	bio_acc = NULL;

	pthread_exit(NULL);
    	return NULL;
}
Exemple #26
0
int main(int argc, char *argv[])
{
    SSL_library_init();
    SSL_load_error_strings();
    
    SSL * new_ssl;
    SSL_CTX * new_ctx;
    
    new_ctx = dh_setup_ctx();
    
    BIO * acc, * client;
    char port[sizeof(argv[1])] = "";  
    int check = 0;
    long port_num;
    parse_port(argc,argv,port);
    acc = BIO_new_accept("1300");
    port_num = BIO_set_accept_port(acc,port);
    if ( !acc )
    { 
	printf("%s \n", "Error in new bio accept");
	return -1;
    }
    if ( BIO_do_accept(acc) <= 0)
    {
	printf("%s \n", "Error in do accept" );
	return -1;
    }
    int get = 0;
    while ( 1 )
    {
	if( BIO_do_accept(acc) <= 0 )
	{
	    printf("%s \n", "Error in accepting connections");
	    return -1;
	}
	client = BIO_pop(acc);
	if ( !(new_ssl = SSL_new(new_ctx)))
	{
	    printf("%s \n", "Error in creating new SSL");
	    return -1;
	}
	SSL_set_bio(new_ssl,client,client);
	if( SSL_accept(new_ssl) <= 0 )
	{
	    get = SSL_get_error(new_ssl,get);
	    printf("%s \n", "Error in accepting SSL connection");
	    printf("%d \n", get);
	    printf("%s \n",ERR_error_string(get,NULL)); 
	    return -1;
	}
	int buf[256] = { 0 };
	int count = 0;
	if ( SSL_read(new_ssl,buf,sizeof(buf)) > 0)
	{
	    /*get = SSL_get_error(new_ssl,get);
	    printf("%d \n", get);
	    printf("%s \n",ERR_error_string(get,NULL)); 
*/
	    while( (char)buf[count] != EOF )
	    {
		printf("%c" , (char)buf[count]);
		count++;
	    }
	}
	SSL_shutdown(new_ssl);
	SSL_free(new_ssl);
    }
    SSL_CTX_free(new_ctx);
    BIO_free(acc);
    return 0;
}
void *emergency_delegation_list_loading_main(void *arg)
{
	BIO     *bio_acc    = NULL;
	BIO     *bio_client = NULL;
    	SSL     *ssl_client = NULL;
    	SSL_CTX *ctx        = NULL;

	int     err;
	char    *host[1];

    	ctx = setup_server_ctx(EMS_CERTFILE_PATH, EMS_CERTFILE_PASSWD, PHR_ROOT_CA_ONLY_CERT_CERTFILE_PATH);
    	bio_acc = BIO_new_accept(EMS_EMERGENCY_DELEGATION_LIST_LOADING_PORT);
    	if(!bio_acc)
        	int_error("Creating server socket failed");
  
    	if(BIO_do_accept(bio_acc) <= 0)
        	int_error("Binding server socket failed");
  
    	for(;;)
    	{
        	if(BIO_do_accept(bio_acc) <= 0)
            		int_error("Accepting connection failed");
 
        	bio_client = BIO_pop(bio_acc);

        	if(!(ssl_client = SSL_new(ctx)))
            		int_error("Creating SSL context failed");

        	SSL_set_bio(ssl_client, bio_client, bio_client);
		if(SSL_accept(ssl_client) <= 0)
		{
        		fprintf(stderr, "Accepting SSL connection failed\n");
			goto ERROR_AT_SSL_LAYER;
		}

		host[0] = USER_CN; 
    		if((err = post_connection_check(ssl_client, host, 1, true, GLOBAL_authority_name)) != X509_V_OK)
    		{
        		fprintf(stderr, "Checking peer certificate failed\n\"%s\"\n", X509_verify_cert_error_string(err));
        		goto ERROR_AT_SSL_LAYER;
    		}

		// Process types of request
		if(!process_request(ssl_client))
			goto ERROR_AT_SSL_LAYER;

ERROR_AT_SSL_LAYER:

		SSL_cleanup(ssl_client);
		ssl_client = NULL;
    		ERR_remove_state(0);
    	}
    
    	SSL_CTX_free(ctx);
	ctx = NULL;

    	BIO_free(bio_acc);
	bio_acc = NULL;

	pthread_exit(NULL);
    	return NULL;
}
Exemple #28
0
int main(int argc, char *argv[])
{
    char *port = NULL;
    BIO *ssl_bio, *tmp;
    SSL_CTX *ctx;
    char buf[512];
    int ret = 1, i;

    if (argc <= 1)
        port = "*:4433";
    else
        port = argv[1];

    signal(SIGINT, close_up);

    SSL_load_error_strings();

    /* Add ciphers and message digests */
    OpenSSL_add_ssl_algorithms();

    ctx = SSL_CTX_new(TLS_server_method());
    if (!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
        goto err;
    if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
        goto err;
    if (!SSL_CTX_check_private_key(ctx))
        goto err;

    /* Setup server side SSL bio */
    ssl_bio = BIO_new_ssl(ctx, 0);

    if ((in = BIO_new_accept(port)) == NULL)
        goto err;

    /*
     * This means that when a new connection is accepted on 'in', The ssl_bio
     * will be 'duplicated' and have the new socket BIO push into it.
     * Basically it means the SSL BIO will be automatically setup
     */
    BIO_set_accept_bios(in, ssl_bio);

again:
    /*
     * The first call will setup the accept socket, and the second will get a
     * socket.  In this loop, the first actual accept will occur in the
     * BIO_read() function.
     */

    if (BIO_do_accept(in) <= 0)
        goto err;

    for (;;) {
        i = BIO_read(in, buf, 512);
        if (i == 0) {
            /*
             * If we have finished, remove the underlying BIO stack so the
             * next time we call any function for this BIO, it will attempt
             * to do an accept
             */
            printf("Done\n");
            tmp = BIO_pop(in);
            BIO_free_all(tmp);
            goto again;
        }
        if (i < 0)
            goto err;
        fwrite(buf, 1, i, stdout);
        fflush(stdout);
    }

    ret = 0;
err:
    if (ret) {
        ERR_print_errors_fp(stderr);
    }
    BIO_free(in);
    exit(ret);
    return (!ret);
}
Exemple #29
0
/******
 * Everything starts here...
 ******/
int main(int argc, char **argv)
{
  BIO *abio = NULL;
  BIO *biobuf = NULL;
  int rc = 0;

  if (rc = init(argc, argv, &cfg))
    goto done;

  signal(SIGQUIT, SIGQUIThandler);
  
  /* We need a BIO to accept connections */
  abio = BIO_new_accept(cfg->hostport);
  if (!abio)
  {
    fprintf(stderr, "Unable to create a new accept BIO.\n");
    rc = -1;
    goto done;
  }
  BIO_set_bind_mode(abio, BIO_BIND_REUSEADDR);
  if ((rc = BIO_do_accept(abio)) <= 0)
  {
    fprintf(stderr, "Unable to accept connections.\n");
    goto done;
  }

  /* And we add a buffer BIO that will be duplicated for each created
   * connections
   */
  biobuf = BIO_new(BIO_f_buffer());
  if (!biobuf)
  {
    fprintf(stderr, "Unable to create a buffer BIO.\n");
    rc = -1;
    goto done;
  }
  BIO_set_accept_bios(abio, biobuf);

  /* Release all rights and go background */
  if (!cfg->debug)
  {
    changeidentity(cfg->user, cfg->group);
    beadaemon();
  }

  while (1)
  {
    BIO *cbio = NULL;

    /* This is a blocking call */
    BIO_do_accept(abio);

    /* A connection has arrived, detach the corresponding BIO and
     * process the request
     */
    cbio = BIO_pop(abio);
    processrequest(cbio);
  }
  
done:
  BIO_free(abio);
  return rc;
}
Exemple #30
0
bool TLS_SOCKET_CLASS::listen()

//  DESCRIPTION     : Setup the listen port.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           :
//<<===========================================================================
{
	ostringstream listenPort;

	// make sure the socket is not already in use
	if (terminatingM)
	{
		if (loggerM_ptr) 
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - In process of terminating.  Cannot listen.");
		}

		// return - in process of termintating
		return false;
	}
	if (connectedM)
	{
		if (loggerM_ptr) 
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Already connected to \"%s\".  Cannot listen to port %d.", 
				remoteHostnameM.c_str(), localListenPortM);
		}

		// return - already connected
		return false;
	}
	else if (listeningM)
	{
		if (loggerM_ptr)
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Socket is already listening to port %d.  Cannot listen again.", 
				localListenPortM);
		}

		// return - socket is already being used to listen
		return false;
	}
	listeningM = false;

	if (loggerM_ptr) 
	{
		loggerM_ptr->text(LOG_DEBUG, 1, "Secure Socket - tls::listen(%d)", localListenPortM);
	}
 
	if (acceptBioM_ptr != NULL)
	{
		BIO_free(acceptBioM_ptr);
		acceptBioM_ptr = NULL;
	}

	// create the socket
	listenPort << localListenPortM;
	acceptBioM_ptr = BIO_new_accept(const_cast<char *>(listenPort.str().c_str()));
	if (acceptBioM_ptr == NULL)
	{
		openSslError("creating server socket to port %d", localListenPortM);
		return false;
	}

	// bind to the port
	if (BIO_do_accept(acceptBioM_ptr) <= 0)
	{
		openSslError("binding server socket to port %d", localListenPortM);
		BIO_free(acceptBioM_ptr);
		acceptBioM_ptr = NULL;
		return false;
	}
 
	// listen socket set up
	listeningM = true;

	// return whether listening or not
	return listeningM;
}