Exemplo n.º 1
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");
}
Exemplo n.º 2
0
static int openssl_ssl_ctx_new_bio(lua_State*L)
{
  SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx");
  const char* host_addr = luaL_checkstring(L, 2);
  int server = lua_isnoneornil(L, 3) ? 0 : auxiliar_checkboolean(L, 3);
  int autoretry = lua_isnoneornil(L, 4) ? 1 : auxiliar_checkboolean(L, 4);

  SSL *ssl = NULL;
  BIO *bio = server ? BIO_new_ssl(ctx, 0) : BIO_new_ssl_connect(ctx);
  int ret = BIO_get_ssl(bio, &ssl);
  if (ret == 1 && ssl)
  {
    if (autoretry)
      SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    if (server)
    {
      BIO* acpt = BIO_new_accept((char*)host_addr);
      BIO_set_accept_bios(acpt, bio);
      bio = acpt;
    }
    else
    {
      ret = BIO_set_conn_hostname(bio, host_addr);
    }
    if (ret == 1)
    {
      PUSH_OBJECT(bio, "openssl.bio");
      openssl_newvalue(L, bio);

      lua_pushboolean(L, 1);
      openssl_setvalue(L, bio, "free_all");

      return 1;
    }
    else
      return openssl_pushresult(L, ret);
  }
  else
  {
    BIO_free(bio);
    bio = NULL;
    return 0;
  }
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
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);
  }
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}