Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9233421
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T06:32:58+00:00 2026-06-18T06:32:58+00:00

I found a pretty good SSL/TLS server-client example in C and I wanted to

  • 0

I found a pretty good SSL/TLS server-client example in C and I wanted to adapt it for use with the BIO library. And I pretty much succeeded except one error I get when running the server:

$ ./ssl-server
68671:error:140950D3:SSL routines:SSL3_READ_N:read bio not set:/SourceCache/OpenSSL098/OpenSSL098-35.1/src/ssl/s3_pkt.c:203:

I’m using gcc -o ssl-server SSL-Server.c -lssl -lcrypto -Wall to compile the server:

//SSL-Server.c
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <resolv.h>
#include "openssl/ssl.h"
#include "openssl/err.h"

#define FAIL -1
#define PORT "2013"

SSL_CTX* InitServerCTX(void)
{
    SSL_METHOD *method;
    SSL_CTX *ctx;

    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    method = SSLv3_server_method();
    ctx = SSL_CTX_new(method);

    if( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }

    return ctx;
}

void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
    if( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }

    if( SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }

    if( !SSL_CTX_check_private_key(ctx) )
    {
        fprintf(stderr, "Private key does not match the public certificate\n");
        abort();
    }
}

void ShowCerts(SSL* ssl)
{
    X509 *cert;
    char *line;

    cert = SSL_get_peer_certificate(ssl);
    if ( cert != NULL )
    {
        printf("Server certificates:\n");
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        printf("Subject: %s\n", line);
        free(line);
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        printf("Issuer: %s\n", line);
        free(line);
        X509_free(cert);
    }
    else
    {
        printf("No certificates.\n");
    }
}

void Servlet(SSL* ssl)
{
    char buf[1024];
    int sd, bytes;

    if( SSL_accept(ssl) == FAIL )
    {
        ERR_print_errors_fp(stderr);
    }
    else
    {
        ShowCerts(ssl);
        bytes = SSL_read(ssl, buf, sizeof(buf));

        if( bytes > 0 )
        {
            buf[bytes] = 0;
            printf("Client msg: \"%s\"\n", buf);
            SSL_write(ssl, "back message", strlen("back message"));
        }
        else
        {
            ERR_print_errors_fp(stderr);
        }
    }

    sd = SSL_get_fd(ssl);
    SSL_free(ssl);
    close(sd);
}

int main(int count, char *strings[])
{
    SSL_CTX *ctx;
    BIO *acc, *client;

    SSL_library_init();

    ctx = InitServerCTX();
    LoadCertificates(ctx, "mycert.pem", "mycert.pem");

    acc = BIO_new_accept(PORT);
    if(!acc)
    {
        printf("Error creating server socket");
    }
    while(1)
    {
        if(BIO_do_accept(acc) <= 0)
        {
            printf("Error binding server socket");
        }

        SSL *ssl;
        client = BIO_pop(acc);
        if(!(ssl = SSL_new(ctx)))
        {
            printf("Error creating SSL context");
        }
        SSL_set_bio(ssl, client, client);

            // Here should be created threads
        Servlet(ssl); 
    }

    SSL_CTX_free(ctx);
}

I’m using gcc -o ssl-client SSL-Client.c -lssl -lcrypto -Wall to compile the client:

//SSL-Client.c
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>

#define FAIL -1
#define SERVER "localhost"
#define PORT "2013"

SSL_CTX* InitCTX(void)
{
    SSL_METHOD *method;
    SSL_CTX *ctx;

    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    method = SSLv3_client_method();
    ctx = SSL_CTX_new(method);

    if( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }

    return ctx;
}

void ShowCerts(SSL* ssl)
{
    X509 *cert;
    char *line;

    cert = SSL_get_peer_certificate(ssl);
    if( cert != NULL )
    {
        printf("Server certificates:\n");
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        printf("Subject: %s\n", line);
        free(line);
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        printf("Issuer: %s\n", line);
        free(line);
        X509_free(cert);
    }
    else
    {
        printf("No certificates.\n");
    }
}

int main(int count, char *strings[])
{
    SSL_CTX *ctx;
    SSL *ssl;
    BIO *conn;
    char buf[1024];
    int bytes;

    SSL_library_init();
    ctx = InitCTX();

    conn = BIO_new_connect(SERVER ":" PORT);
    if(!conn)
    {
        printf("Error creating connection BIO");
    }
    if(BIO_do_connect(conn) <= 0)
    {
        printf("Error connecting to remote machine");
    }

    ssl = SSL_new(ctx);
    SSL_set_bio(ssl, conn, conn);

    if( SSL_connect(ssl) <= 0 )
    {
        printf("Error connecting SSL object");
    }
    else
    {
        printf("Connected!");
        ShowCerts(ssl);
        SSL_write(ssl, "ana are mere", strlen("ana are mere") );

        bytes = SSL_read(ssl, buf, sizeof(buf));
        printf("%s\n", buf);

        SSL_free(ssl);
    }

    SSL_CTX_free(ctx);

    return 0;
}

I’m generating the certificate with the openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem command.

Everything works well and the messages are sending OK. Please ignore the lack of error checking and excuse the total mess in the code, it’s just for learning purposes.

Can anyone point me what’s wrong? Also can you tell if I’m doing major mistakes, I’m trying to learn?(e.g. routine call order, major security problems, etc.)

Thanks!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T06:32:59+00:00Added an answer on June 18, 2026 at 6:32 am

    According to the manual page (the example code at the bottom is very illustrative), the first call to BIO_do_accept() will set up the accept BIO and does nothing else. Only the second and all subsequent calls will be actual calls to accept connections. This is quite illustrative of why OpenSSL will never win an award for «most intuitive API design».

    So what happens in your code? You only call BIO_do_accept() within the loop. First time through the loop, it will set up the BIO and return immediately. Your code calls Servlet() on the inexisting connection, and SSL_accept() fails, returning the error you are seeing. After Servlet() returns, your code loops happily into the second invocation of BIO_do_accept() which this time blocks, waiting for the first connection, and everything works as intended from here.

    To fix this, you need to call BIO_do_accept() once before the loop, like this (using your broken style of error handling for consistency — you really need to fix your error handling!):

    [...]
    acc = BIO_new_accept(PORT);
    if(!acc)
    {
        printf("Error creating server socket");
    }
    /* first call is to set up accept BIO */
    if(BIO_do_accept(acc) <= 0)
    {
        printf("Error calling BIO_do_accept() the first time");
    }
    while(1)
    {
        if(BIO_do_accept(acc) <= 0)
        {
            printf("Error binding server socket");
        }
    [...]
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I found this tutorial which pretty much does exactly what I want: http://webstutorial.com/jquery-popup-jquery-slide-popup/jquery Except
I make pretty extensive use of PImpl and something that I've found myself waffling
Well the title pretty much sums the question. The only thing I found is
I've always found SQL Server date formatting to be counter intuitive. I am pretty
In this blog I found a pretty neat example on how to create a
I'm trying to learn the basics of REST and I found a pretty good
I've found the following code at http://snipplr.com/view/2771 Which is pretty good, almost exactly what
iPhone has a pretty good telephone number splitting function, for example: Singapore mobile: +65
I think I have a pretty good understanding of ARC and the proper use
I haven't found a good example or solution for this due to the nature

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.