[Libwebsockets] Verify client SSL certificates with both OpenSSL and CyaSSL

Alexander Bruines alexander.bruines at gmail.com
Tue Mar 17 12:10:12 CET 2015


I am writing a program that uses this wonderfull library and am trying to get SSL client certificates to work with both OpenSSL and CyaSSL.

I've got it working for CyaSSL but OpenSSL remains problematic at best.
Can anybody please help me to get the following working with openssl?
This is the first time I am trying to write a program that uses SSL.

With CyaSSL I used the following code to get it working:

int callback_http(
  struct libwebsocket_context *context,
  struct libwebsocket *wsi,
  enum   libwebsocket_callback_reasons reason,
  void  *user,
  void  *in,
  size_t len
){
  switch( reason ){
    ....
    ....
    case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS:
      {
        char errbuf[256];
        SSL_CTX *ctx = (SSL_CTX*)user;

        // Load the CA cert
        n = CyaSSL_CTX_load_verify_locations( ctx, fn_ca_cert, NULL );
        if( n != 1 ){
          SYSLOG( LOG_ERR,"SSL: problem loading CA certificate bundle %s: %s", fn_ca_cert, CyaSSL_ERR_error_string( n, errbuf ) );
          return 1;
        }

        // Make sure our crl certificate exists
        FILE *fp = fopen( fn_crl_cert, "rt" );
        if( fp ){
          fclose( fp );

          // Load the CRL and activate CRL checking
          n = CyaSSL_CTX_LoadCRL( ctx, path_crl_cert, SSL_FILETYPE_PEM, 0 );
          if( n != 1 ){
            SYSLOG( LOG_ERR, "SSL: problem loading CRL directory: %s", CyaSSL_ERR_error_string( n, errbuf ) );
            return 1;
          }

          n = CyaSSL_CTX_EnableCRL( ctx, 0 );
          if( n != 1 ){
            SYSLOG( LOG_ERR, "SSL: problem enabling CRL: %s", CyaSSL_ERR_error_string( n, errbuf ) );
            return 1;
          }
        }
        else {
          SYSLOG( LOG_ERR, "SSL: problem loading CRL: %s", fn_crl_cert );
          return 1;
        }
      }
      break;

    case LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION:
      {
        n = 0;
        if( !len ){
          char errbuf[256];
          int err = X509_STORE_CTX_get_error( (X509_STORE_CTX*)user );
          int depth = X509_STORE_CTX_get_error_depth( (X509_STORE_CTX*)user );
          CyaSSL_ERR_error_string_n( err, errbuf, sizeof( errbuf ) );
          SYSLOG( LOG_ERR, "SSL: Error: %s (%d), depth: %d", errbuf, err, depth );
          n = 1;
        }
      }
      return n;
    ....
    ....
    default:
      break;
  }
  return 0;
}


With OpenSSL, this is best I've done so far:
It seems to work (as in does not give any errors) and I can even log in using a client certificate, but when the index.html page loads in a webbrowser, LWS_CALLBACK_HTTP will only receive a request for that file.
Any files needed by index.html (like images, css and javascript files) are not loaded.
Also only the first websocket protocol (besides http) seems to work.

    case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS:
      {
        char errbuf[256];
        X509_STORE *store;
        X509_LOOKUP *lookup;

        SSL_CTX *ctx = (SSL_CTX*) user;

        // Enable CRL Checking
        X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
        X509_VERIFY_PARAM_set_flags( param, X509_V_FLAG_CRL_CHECK );
        SSL_CTX_set1_param( ctx, param );

        // Load the CA cert
        n = SSL_CTX_load_verify_locations( ctx, fn_ca_cert, NULL );
        if( n != 1 ){
          n = ERR_get_error();
          SYSLOG( LOG_ERR, "SSL: problem loading CA certificate bundle: %s", ERR_error_string( n, errbuf ) );
          return 1;
        }

        // Load the CRL into memory
        store = SSL_CTX_get_cert_store( ctx );
        lookup = X509_STORE_add_lookup( store, X509_LOOKUP_file() );
        n = X509_load_cert_crl_file( lookup, fn_crl_cert, X509_FILETYPE_PEM );
        if( n != 1 ){
          n = ERR_get_error();
          SYSLOG( LOG_ERR, "SSL: problem loading CRL '%s': %s", fn_crl_cert, ERR_error_string( n, errbuf ) );
          return 1;
        }

        X509_VERIFY_PARAM_free(param);
      }
      break;

By the way, I'm using a selfsigned CA certificate...



More information about the Libwebsockets mailing list