Opened 11 years ago

Closed 10 years ago

Last modified 19 months ago

#400 closed enhancement (wontfix)

ssl_verify_client per location basis

Reported by: Andrey Novikov Owned by:
Priority: minor Milestone:
Component: nginx-module Version:
Keywords: ssl, client, certificate auth Cc:
uname -a: Linux envek-work 3.8.0-29-generic #42-Ubuntu SMP Tue Aug 13 19:40:39 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.5.0
TLS SNI support enabled
(A lot of modules omitted, this is `nginx-extras` package from nginx development PPA)

Description

I want to enable client certificate authentication only for some location.

Example: require certificate ONLY for certificate-based auth.

server {
    listen      80;
    listen      443 ssl;
    server_name myapp.com;
    charset     utf-8;
    root        /path/to/public/dir;
    try_files   $uri $uri/index.html;

    ssl_certificate        /path/to/myapp/certs/myapp.pem;
    ssl_certificate_key    /path/to/myapp/certs/myapp.key;
    ssl_client_certificate /path/to/myapp/certs/myapp_ca.pem;
    ssl_verify_depth       2;

    location = /user/login/certificate {
        ssl_verify_client on;
        # The application itself will check for user existance and validness by certificate
        # The nginx task: pass only users with valid certificates
    }
}

We shouldn't require certificate from new users on all pages
If user have any certificate installed in browser, then with ssl_verify_client optional; on first visit browser will ask user for certificate. It might scare the inexperienced user and experienced user may ask: ‘Why this site asks for my certificate?’

For now ssl_verify_client option allowed only in http and server scope. I suggest allow it's use in location scope.

Current versions produces next error for above config:

2013/08/23 11:00:41 [emerg] 5500#0: "ssl_verify_client" directive is not allowed here in /etc/nginx/sites-enabled/myapp:15

This requires the SSL rehandshake implementation in Nginx. Link: http://forum.nginx.org/read.php?29,173747,173838#msg-173838

Workarounds: using another subdomain or tricky directives (see discussions below)

Discussion 1: http://forum.nginx.org/read.php?29,173747
Discussion 2: http://forum.nginx.org/read.php?10,214169

Change History (4)

comment:1 by Maxim Dounin, 10 years ago

Resolution: wontfix
Status: newclosed

There are no plans to implement this in foreseeable future.

comment:2 by marko.kohtala@…, 20 months ago

Several countries and organizations provide citizen or user certificates on smart cards to identify citizens or organization users. Providing an endpoint that requires a certificate allows the web page to get a reliable identity for the user at no cost to the service.

However requiring a different domain name makes it technically too difficult to deploy.

I suspect it might be simple enough to implement.

There is a production example at https://kortti.tunnistautuminen.suomi.fi/certcheck.

Looking at it with curl (without my certificate)

$ curl -v https://kortti.tunnistautuminen.suomi.fi/certcheck                *   Trying 52.19.250.89:443...
* TCP_NODELAY set
* Connected to kortti.tunnistautuminen.suomi.fi (52.19.250.89) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=FI; L=HELSINKI; O=Digi- ja v▒est▒tietovirasto; CN=kortti.tunnistautuminen.suomi.fi
*  start date: Mar 25 16:22:19 2022 GMT
*  expire date: Mar 25 16:22:19 2023 GMT
*  subjectAltName: host "kortti.tunnistautuminen.suomi.fi" matched cert's "kortti.tunnistautuminen.suomi.fi"
*  issuer: C=FI; O=TeliaSonera; CN=TeliaSonera Server CA v2
*  SSL certificate verify ok.
> GET /certcheck HTTP/1.1
> Host: kortti.tunnistautuminen.suomi.fi
> User-Agent: curl/7.68.0
> Accept: */*
>
* TLSv1.2 (IN), TLS handshake, Hello request (0):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS alert, handshake failure (552):
* OpenSSL SSL_read: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure, errno 0
* Closing connection 0
curl: (56) OpenSSL SSL_read: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure, errno 0

Simply, it can receive the request without sertificate. When it has the location and there is no client certificate, it will send Hello request and Request CERT. Proxy the request forward once the certificate is received.

comment:3 by Maxim Dounin, 20 months ago

I suspect it might be simple enough to implement.

This "simple enough" already resulted in multiple security issues (most notably CVE-2009-3555, but also others, such as CVE-2011-1473), and I would expect more. It also does not work with HTTP/2 and with TLSv1.3. For more information consider, for example, this question, notably this answer and links it contains.

comment:4 by marko.kohtala@…, 19 months ago

Thank you for your helpful reply.

I see even the Post-Handshake Authentication for TLS 1.3 is forbidden.

I tried to find Authorization header based method of providing the certificate, but did not find any. Certificate is really required to authenticate the request, not the connection.

Below is more off-topic background.


These ID cards are very tempting while under-utilized, so I am looking if their use could be made easier.

They are issued in many countries. The card is very good both for service providers and users. It may cost little to the user, but it is free for service providers. Technically simple. And for the user very safe. If the smart card gets lost, the certificate can be revoked. There is no fear of loss of access to an account because authorities verify the person and issue new card to regain access. The subject identifier has a serial number to identify the user even in the case that the subject has been issued a new card after name has been changed (marriage etc.). And use of the card stays between user and the service provider. Authorities do not know where or when it is used.

Use on mobile requires the certificate is used only for login so the user does not need to keep the NFC card on the phone all the time. And session without certificate is needed for users without the card.

This is becoming less of an issue next year in EU. We have a launch of digital identity that does not use the card but works on the mobile phone. It does not rely on client certificate, but the phone issues self-issued OpenID tokens and can talk to service over other channel.

But the ID cards are not going anywhere.

Note: See TracTickets for help on using tickets.