[luci] server certificate verification with luci/httpclient

Bart Van Der Meerssche bart.vandermeerssche at flukso.net
Wed Jun 2 12:51:45 CEST 2010


Hi list,

I managed to get server certificate validation working against cyassl 
with this patch:

Index: libs/nixio/src/tls-context.c
===================================================================
--- libs/nixio/src/tls-context.c        (revision 6186)
+++ libs/nixio/src/tls-context.c        (working copy)
@@ -65,10 +65,6 @@
                 return luaL_error(L, "unable to create TLS context");
         }

-#ifdef WITH_CYASSL
-       SSL_CTX_set_verify(*ctx, SSL_VERIFY_NONE, NULL);
-#endif
-
         return 1;
  }

@@ -131,6 +127,14 @@
                         SSL_CTX_use_certificate_file(ctx, cert, ktype));
  }

+static int nixio_tls_ctx_set_verify_locations(lua_State *L) {
+       SSL_CTX *ctx = nixio__checktlsctx(L);
+       const char *CAfile = luaL_optstring(L, 2, NULL);
+       const char *CApath = luaL_optstring(L, 3, NULL);
+
+       return nixio__tls_pstatus(L, SSL_CTX_load_verify_locations(ctx, 
CAfile, CApath));
+}
+
  static int nixio_tls_ctx_set_key(lua_State *L) {
         SSL_CTX *ctx = nixio__checktlsctx(L);
         const char *cert = luaL_checkstring(L, 2);
@@ -203,6 +207,7 @@
  /* ctx function table */
  static const luaL_reg CTX_M[] = {
         {"set_cert",                    nixio_tls_ctx_set_cert},
+        {"set_verify_locations",       nixio_tls_ctx_set_verify_locations},
         {"set_key",                             nixio_tls_ctx_set_key},
         {"set_ciphers",                 nixio_tls_ctx_set_ciphers},
         {"set_verify",                  nixio_tls_ctx_set_verify},

Notes:
1/ I can't seem pinpoint the reason why the '#ifdef WITH_CYASSL' check 
should be omitted for the validation to work properly. Setting the 
validation to 'peer' in Lua code does not work when this #ifdef is 
included in the library.

2/ There is an error defining SSL_FILETYPE_PEM and SSL_FILETYPE_ASN1 in 
ssh.h for cyassl:
./include/openssl/ssl.h:432:    SSL_FILETYPE_PEM     = 11,
./include/openssl/ssl.h:431:    SSL_FILETYPE_ASN1    = 10,

While openssl (and nixio.tls) expect:
./include/openssl/ssl.h:340:#define SSL_FILETYPE_ASN1   X509_FILETYPE_ASN1
./include/openssl/ssl.h:341:#define SSL_FILETYPE_PEM    X509_FILETYPE_PEM
./include/openssl/x509.h:122:#define X509_FILETYPE_PEM  1
./include/openssl/x509.h:123:#define X509_FILETYPE_ASN1 2

This means that nixio's tls:set_cert and tls:set_key are not likely to 
work with cyassl.

3/ Cyassl's SSL_CTX_load_verify_locations will only work with a CAfile 
being specified. CApath is ignored. Furthermore, cyassl will only load 
the first certificate in the bundle. Specifying a certificate chain by 
putting all certificates in a cacert-type bundle and pointing to this 
file with SSL_CTX_load_verify_locations will not work. With openssl, it 
does.


Cheers,
Bart.

Bart Van Der Meerssche wrote:
> Hi Jow,
> 
> I've recompiled Backfire with openssl as LuCI TLS provider and 
> openssl-utils enabled. The server certificate validation succeeds with 
> the openssl utility command.
> root at OpenWrt:~# openssl s_client -connect api.flukso.net:443 -certform 
> PEM -CAfile /etc/ssl/cacert.pem -msg -state -tls1
> 
> ---
> New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
> Server public key is 2048 bit
> Secure Renegotiation IS NOT supported
> Compression: zlib compression
> Expansion: zlib compression
> SSL-Session:
>      Protocol  : TLSv1
>      Cipher    : DHE-RSA-AES256-SHA
>      Session-ID: [...]
>      Session-ID-ctx:
>      Master-Key: [...]
>      Key-Arg   : None
>      TLS session ticket: [...]
>      Compression: 1 (zlib compression)
>      Start Time: 1275158096
>      Timeout   : 7200 (sec)
>      Verify return code: 0 (ok)
> ---
> 
> Since the -CAfile switch uses SSL_CTX_load_verify_locations to load the 
> sequence of CA certificates contained in cacert.pem, I've added the 
> method to the tls-context.c bindings. I'm including the patch against 
> LuCI trunk inline:
> 
> Index: tls-context.c
> ===================================================================
> --- tls-context.c       (revision 6186)
> +++ tls-context.c       (working copy)
> @@ -131,6 +131,14 @@
>                          SSL_CTX_use_certificate_file(ctx, cert, ktype));
>   }
> 
> +static int nixio_tls_ctx_set_verify_locations(lua_State *L) {
> +       SSL_CTX *ctx = nixio__checktlsctx(L);
> +       const char *CAfile = luaL_optstring(L, 2, NULL);
> +       const char *CApath = luaL_optstring(L, 3, NULL);
> +
> +       return nixio__tls_pstatus(L, SSL_CTX_load_verify_locations(ctx, 
> CAfile, CApath));
> +}
> +
>   static int nixio_tls_ctx_set_key(lua_State *L) {
>          SSL_CTX *ctx = nixio__checktlsctx(L);
>          const char *cert = luaL_checkstring(L, 2);
> @@ -203,6 +211,7 @@
>   /* ctx function table */
>   static const luaL_reg CTX_M[] = {
>          {"set_cert",                    nixio_tls_ctx_set_cert},
> +        {"set_verify_locations",       nixio_tls_ctx_set_verify_locations},
>          {"set_key",                             nixio_tls_ctx_set_key},
>          {"set_ciphers",                 nixio_tls_ctx_set_ciphers},
>          {"set_verify",                  nixio_tls_ctx_set_verify},
> 
> 
> Modifying httpclient.lua to use set_verify_locations allows server 
> certificate validation from within httpclient.lua. So please consider 
> the above patch for inclusion in trunk:
> 
> if pr == "https" then
> 	local tls = options.tls_context or nixio.tls()
> -->	tls:set_verify("peer")
> -->	tls:set_verify_locations("/etc/ssl/cacert.pem")
> 	sock = tls:create(sock)
> 	local stat, code, error = sock:connect()
> 	if not stat then
> 		return stat, code, error
> 	end
> end
> 
> So we're now able to perform certificate validation with openssl as TLS 
> provider. Recompiling Backfire with cyassl as TLS provider still shows 
> the original bug: Setting tls:set_verify("peer") and commenting out 
> tls:set_verify_locations("/etc/ssl/demoCA/cacert.pem") does not cause 
> the server certificate validation to fail (as it does correctly with 
> openssl). The call just proceeds and returns the HTTPS reply body.
> 
> Cheers,
> Bart.
> 
> 
> Jo-Philipp Wich wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Hi.
>>
>>> Could somebody help me out?
>>> Am I using the TLSContext methods correctly?
>> Your code looks correct, can you try it with nixio linked against
>> OpenSSL? I suspect that a bit too much was disabled in CyaSSL build config.
>>
>> ~ Jow
>> -----BEGIN PGP SIGNATURE-----
>> Version: GnuPG v1.4.9 (GNU/Linux)
>> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>>
>> iEYEARECAAYFAkv3QAcACgkQdputYINPTPPMpQCcCKhHLJ+qNJr/qzFt3vjh2tn3
>> H/wAn0Osl6Wf1jKroZ/3fkmJDzU84+Yc
>> =Uxei
>> -----END PGP SIGNATURE-----
>> _______________________________________________
>> luci mailing list
>> luci at lists.subsignal.org
>> https://lists.subsignal.org/mailman/listinfo/luci
>>
> _______________________________________________
> luci mailing list
> luci at lists.subsignal.org
> https://lists.subsignal.org/mailman/listinfo/luci
> 


More information about the luci mailing list