[Libwebsockets] Verifying client certificate

Bruce Perens bruce at perens.com
Wed Aug 5 19:27:08 CEST 2015


To make verification of client certificates work:

Start with my article at
http://blog.algoram.com/blog/2015/06/19/using-the-arrl-logbook-of-the-world-certificate-to-validate-yourself-to-web-services-as-a-licensed-radio-amateur/
for some information and a demo.

Apply my patch at http://algoram.com/tmp/libwebsockets.patch . Take a
look at my change to ssl.c, where I comment out
SSL_VERIFY_FAIL_IF_NO_PEER_CERT. Uncomment that if you want the
program to fail if a certificate is not presented to it.

In your server, handle
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS and load the
entire certificate chain you intend to verify against. The certificate
loading elsewhere in libwebsockets doesn't work for client certificate
verification.

The code will look like this:

case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS:
      {
        SSL_CTX * ssl_context = (SSL_CTX *)user;

        if ( SSL_CTX_load_verify_locations(ssl_context, ETC_DIR PROGRAM_NAME \
         "/certificates/authority/default.pem", 0) != 1 ) {
          std::cerr << "Loading certification authority certificates
failed." << std::endl;
        }
      }
      return 0;

Code that reads out the certificate info will look like this:

static void
get_client_info(libwebsocket_context * context, libwebsocket * wsi,
client_context * client)
{
  X509 * certificate = SSL_get_peer_certificate(wsi->ssl);
  char buffer[256];
  char rip[256];

  if ( certificate ) {
    client->info.certificate_is_valid = SSL_check_private_key(wsi->ssl);
    X509_NAME *subj = X509_get_subject_name(certificate);
    X509_NAME_get_text_by_NID(subj, NID_commonName, buffer, sizeof(buffer));
    client->info.name = strdup(buffer);
    buffer[0] = '\0';
    X509_NAME_get_text_by_NID(subj, NID_pkcs9_emailAddress, buffer,
sizeof(buffer));
    client->info.email = strdup(buffer);
    buffer[0] = '\0';
    X509_NAME_get_text_by_NID(subj, NID_callsign, buffer, sizeof(buffer));
    client->info.callsign = strdup(buffer);
    buffer[0] = '\0';
    rip[0] = '\0';
  }
  else {
    client->info.certificate_is_valid = false;
  }
  libwebsockets_get_peer_addresses(context, wsi,
libwebsocket_get_socket_fd(wsi), buffer, sizeof(buffer), rip,
sizeof(rip));
  client->info.hostname = strdup(buffer);
  client->info.ip_address = strdup(rip);
}

Of course you will not have the NID_callsign field, used above, unless
you are using the ARRL Logbook of the World certificate, which is only
for radio hams. Leave that code out.

    Bruce

On Wed, Aug 5, 2015 at 9:33 AM, Alexander Bruines <andy.green at linaro.org> wrote:
> On 08/05/2015 04:27 PM, techi eth wrote:
>> Thanks for answer.
>>
>> For quick testing if I have server running on some other machine (.Net Client on Windows) & server is expecting client certificate for verification.
>>
>> Is that part is already implemented ?
>>
>> On Wed, Aug 5, 2015 at 7:10 PM, Alexander Bruines <andy.green at linaro.org <mailto:andy.green at linaro.org>> wrote:
>>
>>     On 08/05/2015 02:25 PM, techi eth wrote:
>>     > Hi,
>>     >
>>     > Please let me know how to enable libwebsockets-test-client & libwebsockets-test-server for verifying client certificate by server during connection.
>>     >
>>     > Thanks
>>     >
>>     >
>>     > _______________________________________________
>>     > Libwebsockets mailing list
>>     > Libwebsockets at ml.libwebsockets.org <mailto:Libwebsockets at ml.libwebsockets.org>
>>     > http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>     >
>>
>>     Hi,
>>
>>     This has not been implemented in the test client/server.
>>     I'd write a patch to support it but someone seems to be ignoring anything I send his way...
>>
>>     If you need an example, you could take a look at my project that uses libwebsockets and CyaSSL.
>>      http://sourceforge.net/projects/galaxy4linux/
>>
>>     Btw, it only works when using CyaSSL/wolfSSL.
>>     With openSSL libwebsockets crashes immediately when I turn on LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT....
>>
>>     Regards, Alex
>>     _______________________________________________
>>     Libwebsockets mailing list
>>     Libwebsockets at ml.libwebsockets.org <mailto:Libwebsockets at ml.libwebsockets.org>
>>     http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>
>>
>>
>>
>> _______________________________________________
>> Libwebsockets mailing list
>> Libwebsockets at ml.libwebsockets.org
>> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>
>
> I have no idea about that and I don't know any .net.
> After turning on LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT in your server, your client application should send a client cert when connecting.
> Read the API documentation for libwebsockets...
>
> _______________________________________________
> Libwebsockets mailing list
> Libwebsockets at ml.libwebsockets.org
> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets



More information about the Libwebsockets mailing list