Project

General

Profile

Actions

Feature #1288

closed

SSL Client Certificate validation.

Added by nmaier over 16 years ago. Updated about 12 years ago.

Status:
Fixed
Priority:
Normal
Category:
core
Target version:
ASK QUESTIONS IN Forums:

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


Files

lighty-clientvalidation-trunk.path (6.94 KB) lighty-clientvalidation-trunk.path patch for current trunk nmaier, 2007-08-06 00:45
lighty-clientvalidation-trunk.patch (6.54 KB) lighty-clientvalidation-trunk.patch fixing segfault, wrong patch location (see further comments) nmaier, 2007-08-13 20:06
lighty-clientvalidation-1.4.x.patch (6.71 KB) lighty-clientvalidation-1.4.x.patch fixing segfault, wrong patch location (see further comments) nmaier, 2007-08-13 20:06
lighty-clientcert.tar.gz (13.6 KB) lighty-clientcert.tar.gz fixing segfault, wrong patch location (see further comments) nmaier, 2007-08-13 20:08
lighty-clientvalidation-1.4.x.2.patch (6.64 KB) lighty-clientvalidation-1.4.x.2.patch fixed environment variable duplication when using mod_rewrite presbrey, 2007-08-24 02:35
lighty-clientvalidation-serialenv.patch (1.37 KB) lighty-clientvalidation-serialenv.patch Patch to set serial number of the client certificate into environment -- laurent.corbes Anonymous, 2008-05-21 15:18
lighty-clientvalidation-1.4.20.patch (6.91 KB) lighty-clientvalidation-1.4.20.patch akrus, 2008-12-03 06:47
lighty-clientvalidation-1.4.21.patch (8.74 KB) lighty-clientvalidation-1.4.21.patch akrus, 2009-03-05 08:51
lighty-clientvalidation-1.4.22.patch (8.74 KB) lighty-clientvalidation-1.4.22.patch patch for 1.4.22 (please read comment below) bjuchli, 2009-03-16 18:02
lighttpd-clientverify2-1.4.22.patch (7.53 KB) lighttpd-clientverify2-1.4.22.patch patch for 1.4.22 with SSL_CLIENT_VERIFY variable oleg.smirnov, 2009-03-25 15:20
lighty-sslcert-r2585.patch (6.9 KB) lighty-sslcert-r2585.patch patch to r2585 (trunk) presbrey, 2009-07-14 14:48
lighttpd-1.4.28-clientvalidation-serialenv.patch (1.11 KB) lighttpd-1.4.28-clientvalidation-serialenv.patch cicik, 2010-10-23 13:54

Related issues 3 (0 open3 closed)

Related to Bug #2093: ssl client auth doesn't work... (in 1.4.24)Fixed2009-11-02Actions
Related to Feature #478: Add support for mutually authenticated SSLFixedActions
Has duplicate Feature #921: Client SSL Authentication ModuleFixedjanActions
Actions #1

Updated by nmaier over 16 years ago

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 ;))

Actions #2

Updated by presbrey over 16 years ago

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/" 
}
Actions #3

Updated by nmaier over 16 years ago

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).

Actions #4

Updated by presbrey over 16 years ago

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.

Actions #5

Updated by presbrey over 16 years ago

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)

Actions #6

Updated by presbrey over 16 years ago

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).

Actions #7

Updated by Farcaller over 16 years ago

Any hope to see it released in 1.4.x?

Actions #8

Updated by Anonymous about 16 years ago

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!

-- berto

Actions #9

Updated by hvdkamer almost 16 years ago

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...

Actions #10

Updated by lcorbes almost 16 years ago

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).

Actions #11

Updated by Anonymous almost 16 years ago

Hi, is it possible to set ssl.verifyclient for a folder?
Something like:

$SERVER[[socket]] == "0.0.0.0:443" {
    ssl.engine                 = "enable" 
    $HTTP[[url]] =~ "^/login/" {
        ssl.verifyclient.activate  = "enable" 
        ssl.verifyclient.enforce   = "enable" 
        ssl.verifyclient.depth     = 2
    }
}

Actions #12

Updated by Anonymous over 15 years ago

any news there? :(

Actions #13

Updated by Anonymous over 15 years ago

What is the status of this issue?

Is there any version that supports this?

-- sinister

Actions #14

Updated by stbuehler over 15 years ago

i plan to have a look at it after 1.4.20 got released.

Actions #15

Updated by akrus over 15 years ago

  • % Done changed from 0 to 20

Something new here? :)

Actions #16

Updated by akrus over 15 years ago

  • % Done changed from 20 to 0

Oops, sorry :x

Actions #17

Updated by iuridiniz over 15 years ago

This issue is marked for 1.4.21, so will it be possible on 1.4.21? I'm currently doing this by using stunnel.

Actions #18

Updated by stbuehler over 15 years ago

  • Patch available set to No

As long as the feature request is not "fixed" it obviously isn't included.

Actions #19

Updated by akrus over 15 years ago

Installed lighttpd/1.4.20 with this patch yesterday, works fine, but anyway it would be great the patch is included in mainstream :)

Actions #20

Updated by akrus over 15 years ago

Okay, someone to add CRL support? Would be great...

Actions #21

Updated by akrus over 15 years ago

Uploaded patch for 1.4.20, minor changes, but previous one didn't work as expected :)

currently trying to make $HTTP["url"] support...

Actions #22

Updated by kjikaqawej over 15 years ago

nmaier wrote:

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 ;))

Maybe it's possible where you are, but in .ca and .us you can't put anything into the public domain, unless you're at NASA or some org. that has explicit laws allowing you to do so. Also, with your statement, you effectively put it under a permissive BSD-like licence. Nonetheless, it would be GPL (v2, dunno about v3) compatible. Note, I'm not a lawyer, and you should consult a lawyer for more information.

As for the work itself, thank you :).

Actions #23

Updated by icy about 15 years ago

  • Target version changed from 1.4.21 to 1.4.22
Actions #24

Updated by akrus about 15 years ago

why 1.4.22? lighttpd is missing this feature for sooooo long.

Actions #25

Updated by icy about 15 years ago

True but we wanted to get 1.4.21 out very soon and in fact there is already a RC out (see blog).
We included the most important fixes and some stuff that was particularly easy to commit in that version.
I haven't looked through all these patches and it would need some testing too. Therefor it was set for .22 like all other patches that didn't make it into .21

I am sorry that this feature didn't make it into svn yet but there are limits on how much time we can invest so something is always falling behind :(

Actions #26

Updated by icy about 15 years ago

  • Patch available changed from No to Yes
Actions #27

Updated by stbuehler about 15 years ago

  • Target version changed from 1.4.22 to 1.4.23
Actions #28

Updated by tdussa about 15 years ago

So why has the target version been bounced again?

Actions #29

Updated by jkb about 15 years ago

any chance somebody can make a patch against 1.4.21? our site really needs this feature and would hate to switch to apache for this. thanks.

Actions #31

Updated by icy about 15 years ago

tdussa wrote:

So why has the target version been bounced again?

Because 1.4.22 is an important bugfix release that needs to be pushed out as fast as possible. Mostly concerning FreeBSD users.

Sorry, again :(
And thanks to nmaier, presbrey and akrus for working on the patches! I will keep an eye on this one.

Actions #32

Updated by jkb about 15 years ago

solved my problem, deleting previous note. sorry about this..

Actions #33

Updated by bjuchli about 15 years ago

Hi everybody,
i've updated the patch to 1.4.22. I've never made a patch before... so here's what i did:
Compared the the files 1.4.21 files to the 1.4.21 files that are affected by the patch (1.4.21).
Since only only /src/server.c has changed i've adjusted line 209 of the patch from

@@ -275,6 +275,7 @@
to
@@ -278,6 +278,7 @@

since the altered code section has moved down 3 lines but has not changed itself.
I think i should work. At least it seems to work for me ;-)

Actions #34

Updated by oleg.smirnov about 15 years ago

I checked patch for 1.4.22 -- it actually works, and wrote one more feauture: now it sets SSL_CLIENT_VERIFY env variable in the same way as mod_ssl does.

Actions #35

Updated by icy about 15 years ago

  • Target version changed from 1.4.22 to 1.4.23

Please don't set target version to something already released. It's the version that is planed to include the change.

Actions #36

Updated by jkb about 15 years ago

hi... is there a way to do client authentication based on URL string or Agent string?

Actions #37

Updated by akrus about 15 years ago

jkb wrote:

hi... is there a way to do client authentication based on URL string or Agent string?

You may write a new patch that will support it :) currently there's no support for this kind of authorization, only 'enable' or 'disable'.

Actions #38

Updated by hamar almost 15 years ago

How can I authenticate users with certificates coming from multiple CAs? Is there a way to configure the CA certificate path, something equivalent to the SSLCACertificatePath directive in apache?

Actions #39

Updated by nipil almost 15 years ago

hamar wrote:

How can I authenticate users with certificates coming from multiple CAs? Is there a way to configure the CA certificate path, something equivalent to the SSLCACertificatePath directive in apache?

As far as i know, you can add the different CA certificates to the ca-file. Maybe you could ask hvdkamer (who posted above), he does this kind of multiple acceptance in his testbed located at https://test.hetlab.tk.

Actions #40

Updated by stbuehler almost 15 years ago

Okay... how to get this upstream: I want one clean patch for the latest released version (1.4.22 now). Porting it to trunk shouldn't be too difficult after that.

This means that the involved developers should be included in that patch (if they want to), and all used environment variables should be documented; and i think it would be nice to have some more "standard" (i.e. Apache) variables there.

I tried to find the time to do this myself... but as you see, nothing happend yet. So if you want to help getting this upstream, you know what to do :)

Actions #41

Updated by stbuehler almost 15 years ago

  • Target version changed from 1.4.23 to 1.4.24
Actions #42

Updated by presbrey over 14 years ago

Attached patch to latest trunk (r2585). Compatible with GSSAPI patch (#1899).

Actions #43

Updated by nicolas314 over 14 years ago

Just my 2 cents on the topic: mod_ssl forwards a lot more variables than what the current patch seems to offer. A quick glance shows:
SSL_CIPHER, SSL_CIPHER_ALGKEYSIZE,
SSL_CIPHER_EXPORT, SSL_CIPHER_USEKEYSIZE,
SSL_CLIENT_CERT, SSL_CLIENT_VERIFY,
SSL_COMPRESS_METHOD, SSL_PROTOCOL,
SSL_SERVER_A_KEY, SSL_SERVER_A_SIG,
SSL_SERVER_CERT, SSL_SERVER_I_DN,
SSL_SERVER_I_DN_CN, SSL_SERVER_I_DN_O,
SSL_SERVER_M_SERIAL, SSL_SERVER_M_VERSION,
SSL_SERVER_S_DN, SSL_SERVER_S_DN_C,
SSL_SERVER_S_DN_CN, SSL_SERVER_S_DN_O,
SSL_SERVER_S_DN_OU, SSL_SERVER_V_END,
SSL_SERVER_V_START SSL_VERSION_INTERFACE
SSL_VERSION_LIBRARY

Most important for client certificate validation would be to pass the client certificate itself, which would allow web apps to dig out whatever values they need.
Many thanks for bringing this to lighttpd!

Actions #44

Updated by stbuehler over 14 years ago

  • Assignee deleted (jan)
  • Priority changed from High to Normal
  • Target version changed from 1.4.24 to 1.4.x
  • Missing in 1.5.x set to No

I pushed the basic verification support now; but the environment vars are missing for now (I really think the vars should be documented in the code) - I agree with nicolas314: we should at least export the client cert, and the others should be included too.

Actions #45

Updated by patrickdk over 14 years ago

nicolas314 wrote:

SSL_CIPHER, SSL_CIPHER_ALGKEYSIZE,
SSL_CIPHER_EXPORT, SSL_CIPHER_USEKEYSIZE,
SSL_COMPRESS_METHOD, SSL_PROTOCOL,
SSL_SERVER_A_KEY, SSL_SERVER_A_SIG,
SSL_SERVER_CERT, SSL_SERVER_I_DN,
SSL_SERVER_I_DN_CN, SSL_SERVER_I_DN_O,
SSL_SERVER_M_SERIAL, SSL_SERVER_M_VERSION,
SSL_SERVER_S_DN, SSL_SERVER_S_DN_C,
SSL_SERVER_S_DN_CN, SSL_SERVER_S_DN_O,
SSL_SERVER_S_DN_OU, SSL_SERVER_V_END,
SSL_SERVER_V_START SSL_VERSION_INTERFACE
SSL_VERSION_LIBRARY

Shouldn't all those be a seperate issue? those should be passed on any ssl session, and not a client thing
I agree the client_cert belongs on this ticket though.

Actions #46

Updated by nicolas314 over 14 years ago

patrickdk wrote:

Shouldn't all those be a seperate issue?

You are right, sorry. Server-side and protocol-related SSL variables should always be present whenever SSL is used. Client-side variables: the client certificate is a minimum, splitting it into components would probably be very appreciated by application writers.

Actions #47

Updated by ostehovel over 14 years ago

  • File diff.patch added

I just made a patch by combinding some other patches in this thread.
This patch was made from rev #2656 of the trunk

and if you find any mistakes, bad typing stuff like that please re-upload a corrected version please ;D

Oste Hovel

Actions #48

Updated by icy over 14 years ago

  • File deleted (diff.patch)
Actions #49

Updated by stbuehler over 14 years ago

  • Status changed from New to Fixed
  • % Done changed from 0 to 100

Applied in changeset r2688.

Actions #50

Updated by stbuehler over 14 years ago

  • Target version changed from 1.4.x to 1.4.25
Actions #51

Updated by cicik over 13 years ago

Here is a patch for lighttpd 1.4.28 that sets serial number of the client certificate into environment. Previous patch won't work with this version of lighttpd.

Actions #52

Updated by gstrauss over 7 years ago

  • Related to Bug #2093: ssl client auth doesn't work... (in 1.4.24) added
Actions #53

Updated by gstrauss over 7 years ago

  • Related to Feature #478: Add support for mutually authenticated SSL added
Actions

Also available in: Atom