Ticket #1288 (new enhancement)

Opened 13 months ago

Last modified 4 weeks ago

SSL Client Certificate validation.

Reported by: nmaier Owned by: jan
Priority: high Milestone:
Component: core Version: 1.4.19
Severity: major Keywords:
Cc: nmaier, farcaller, lcorbes Blocked By:
Need User Feedback: no Blocking:

Description

I took the opportunity to port #921 to trunk, enhance it and the port it back to 1.4.x branch ;)

Lighttpd should support SSL Client Certificate validating. There are a lot of good use-cases for this.

And most importantly Apache mod_ssl supports it :p

Attachments

lighty-clientvalidation-trunk.path (6.9 kB) - added by nmaier 13 months ago.
patch for current trunk
lighty-clientvalidation-trunk.patch (6.5 kB) - added by nmaier 13 months ago.
fixing segfault, wrong patch location (see further comments)
lighty-clientvalidation-1.4.x.patch (6.7 kB) - added by nmaier 13 months ago.
fixing segfault, wrong patch location (see further comments)
lighty-clientcert.tar.gz (13.6 kB) - added by nmaier 13 months ago.
fixing segfault, wrong patch location (see further comments)
lighty-clientvalidation-1.4.x.2.patch (6.6 kB) - added by presbrey 13 months ago.
fixed environment variable duplication when using mod_rewrite
lighty-clientvalidation-serialenv.patch (1.4 kB) - added by laurent.corbes@… 4 months ago.
Patch to set serial number of the client certificate into environment

Change History

Changed 13 months ago by nmaier

patch for current trunk

  Changed 13 months ago by nmaier

Lighttpd Client Certificate Validation README

A patchset to add support for validation client side ssl certificates to lighty.

Contents

  • lighty-clientvalidation-1.4.x.patch - against branches/lighttpd-1.4.x@1882
  • lighty-clientvalidation-trunk.patch - against trunk@1878
  • test/ca.crt - CA Cert used when conducting the testing
  • test/server.prem - Server Certificate (pemfile) during testing
  • test/client.p12 - Client Certificate during testing; password=test
  • test/lighttpd14.conf - test conf for the 1.4.x branch
  • test/lighttpd.conf - test conf for the trunk

New configuration

  • bool ssl.verifyclient.activate - Activate the functionality; default=disable
  • bool ssl.verifyclient.enforce - Only let clients with a cert in; default=enable
  • short ssl.verifyclient.depth - Depth of validation that OpenSSL should perform; default=9
  • string ssl.verifyclient.username - Use this Certificate entry as a username which will be passed to (most) handlers

Idea

My goal was to add validation of client certs to lighttpd. I tried to keep somewhat compatible with apache2.

Apache will set REMOTE_USER. This implementation does as well (.username) but additionally provides all SSL_CLIENT_DN_* entries.

Webapps/handlers may use this information for fine grained authentication/identity checking.

Allowing the client to not provide a certificate (see: .enforce/REMOTE_USER/SSL_CLIENT_DN_*) might provide webapps with the ability to allow also anonymous access. This is turned off by default to protect against "lazy people" ;)

The CA file it will use is configured through ssl.ca-file.

Testing

I carried out testing on two system:

  • Ubuntu Feisty / PHP5.2.1
  • Debian Sarge / PHP5.2.3-0.dotdeb.0

Browsers tested

  • Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.6 (Ubuntu-feisty)
  • Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a7pre) Gecko/2007072118 Minefield/3.0a7pre
  • Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6
  • Opera/9.22 (Windows NT 5.1; de) (Opera sucks for CS btw :p)
  • Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)

Tested was against a static index.html, a favicon and a phpinfo() script via php5-fcgi.

Known issues

  • It seems that CA certs using other than sha1 fail.
  • At the moment lighty screams about a lot of read errors. This will also happen without this patchset

Acknowledgements

Copyright/License

The authors disclaims copyright to the code thereby placing it into public domain. Lighttpd Devs may simply take this and interoperate this into lighty without legal problems. (I would be thankful for some credit however, and I guess Lars would too ;))

follow-up: ↓ 3   Changed 13 months ago by presbrey

  • cc nmaier added

Conditional configurations prevent SSL_ environment variables from being passed to CGI. A snippet from the failing case follows:

$SERVER["socket"] == "0.0.0.0:443" {
    ssl.engine                 = "enable"
    ssl.verifyclient.activate  = "enable"
    ssl.verifyclient.enforce   = "enable"
    ssl.verifyclient.depth     = 2
    server.document-root       = "/srv/www/root-ssl/"
}

Changed 13 months ago by nmaier

fixing segfault, wrong patch location (see further comments)

Changed 13 months ago by nmaier

fixing segfault, wrong patch location (see further comments)

Changed 13 months ago by nmaier

fixing segfault, wrong patch location (see further comments)

in reply to: ↑ 2 ; follow-up: ↓ 4   Changed 13 months ago by nmaier

Replying to presbrey:

Conditional configurations prevent SSL_ environment variables from being passed to CGI. ...

I had the code that adds the envvars in the wrong place, i.e. before the config was merged. Hence only the global context was recognized. Should be fixed by now.

Furthermore I fixed an error causing segfaults when the ssl.engine and verifyclient are enabled but later the engine is conditionally disabled again.
(Hence the ssl stuff is random and openssl crashed).

in reply to: ↑ 3   Changed 13 months ago by presbrey

Replying to nmaier:

Getting close nmaier... here's the next bug. In a script resolved via url.rewrite-once (i.e: url.rewrite-once += ( "/main/do/([\?]+)(\??.*)" => "/main/$1.php$2" )), environment variables' values are injected twice producing duplicated values:

_ENVSSL_CLIENT_S_DN_C? US, US _ENVSSL_CLIENT_S_DN_ST? State, State _ENVSSL_CLIENT_S_DN_CN? presbrey, presbrey _ENVSSL_CLIENT_S_DN_EMAILADDRESS? presbrey@…, presbrey@…

...etc.

follow-up: ↓ 11   Changed 13 months ago by presbrey

Replying to nmaier:

Getting close nmaier... here's the next bug. In a script resolved via url.rewrite-once (i.e: url.rewrite-once += ( "^/main/do/([^\?]+)(\??.*)" => "/main/$1.php$2" )), environment variables' values are injected twice producing duplicated values:

_ENV["SSL_CLIENT_S_DN_C"]	US, US
_ENV["SSL_CLIENT_S_DN_ST"]	State, State
_ENV["SSL_CLIENT_S_DN_CN"]	presbrey, presbrey
_ENV["SSL_CLIENT_S_DN_EMAILADDRESS"]	presbrey@foo.bar, presbrey@foo.bar

...etc.

(fixed trac comment formatting)

Changed 13 months ago by presbrey

fixed environment variable duplication when using mod_rewrite

  Changed 13 months ago by presbrey

Moving the call to https_add_ssl_entries below plugins_call_handle_uri_raw in response.c fixes the issue I reported (attached new patch above).

  Changed 11 months ago by Farcaller

  • cc farcaller added

Any hope to see it released in 1.4.x?

  Changed 6 months ago by berto

Is there any chance to see support for Certificate Revocation Lists? This would be ideal in case certificates are compromised.

Great work on this patch, by the way, thanks!

  Changed 4 months ago by hvdkamer

I've backported this patch to the version shipped in Debian Etch. It works great. However in Apache the complete presented certificate can be exported in an environment variable. Is it possible to do the same in Lighttpd? See the Apache documentation:

http://www.apache-ssl.org/docs.html#SSLExportClientCertificates

With the complete certificate more rigoreus testing of the authentication would be possible. For example in this setup:

https://test.hetlab.tk/certlogin/

I accept certificates from CAcert, Ascertia, StartSSL and my own CA. I now use the e-mailaddress because that one is in the three free certificate providers tested with a mailprobe. In this case someone can use the same e-mailaddress in all certificate providers and still be mapped to the same account. Not a real problem, but with access to the certificate we could use the fingerprint in a tighter control. The above question could also be done in the application code. In this case checking the CRL is better be done in the server? Anyway, access to the complete certificate could be ice in more scenarios...

Changed 4 months ago by laurent.corbes@…

Patch to set serial number of the client certificate into environment

  Changed 4 months ago by lcorbes

  • cc lcorbes added

Hi all,

I don't know if it will be usefull to someone else but I add a patch to get the serial number of the client certificate in environment variables.

This allow us to check it for authentification thru a cgi script.

(The patch works on 1.4.19, will check for 1.5.x if needed).

in reply to: ↑ 5   Changed 3 months ago by anonymous

  • version changed from 1.5.x-svn to 1.4.19

Hi, is it possible to set ssl.verifyclient for a folder? Something like: $SERVERsocket? == "0.0.0.0:443" {

ssl.engine = "enable" $HTTPurl? =~ "/login/" {

ssl.verifyclient.activate = "enable" ssl.verifyclient.enforce = "enable" ssl.verifyclient.depth = 2

}

}

  Changed 4 weeks ago by anonymous

any news there? :(

Add/Change #1288 (SSL Client Certificate validation.)

Author



Change Properties
<Author field>
Action
as new
 
Note: See TracTickets for help on using tickets.