Skip to content

crypto/tls: client-cert EKU is enforced. #7423

Description

@ncw
I think Go is making a mistake in assuming that client certificates
without the extended usage attributes (ie most client certificates)
should be denied use as a client authentication.

What steps will reproduce the problem?

Here are a couple of programs and a script to demonstrate the problem

https://gist.github.com/ncw/9253562

What is the expected output?

Working SSL connection

What do you see instead?

tls: client's certificate's extended key usage doesn't permit it to be used for client
authentication

Which operating system are you using?

Linux Ubuntu 13.10

Which version are you using?  (run 'go version' or 'gccgo --version')

(latest head)

go version devel +abd51e52924a Thu Feb 27 01:45:22 2014 -0800 linux/amd64

Please provide any additional information below.

Here is the README from the gist

This demonstrates a bug in Go

First generate the certificates with

./makecert.sh test@test.com

Run the server in one terminal

go run server.go

Run the client in the other

go run client.go

You'll see an SSL negotiation failure

The Server says

2014/02/27 16:33:51 server: listening
2014/02/27 16:33:53 server: accepted from 127.0.0.1:43700
2014/02/27 16:33:53 server: conn: type assert to TLS succeedded
2014/02/27 16:33:53 server: handshake failed: tls: client's certificate's extended key
usage doesn't permit it to be used for client authentication
exit status 1

And the Client says

2014/02/27 16:33:53 client: dial: remote error: handshake failure
exit status 1

If you then try to add the extended usage to the certificate with the -addtrust
clientAuth (uncomment in makecert.sh) you get this from the Client

2014/02/27 16:36:58 server: loadkeys: crypto/tls: failed to parse certificate PEM data
exit status 1

Because the client can no longer read the certificate which now starts with

-----BEGIN TRUSTED CERTIFICATE-----
MIIDizCCAnMCAQEwDQYJKoZIhvcNAQEFBQAwgZExCzAJBgNVBAYTAkRFMQwwCgYD

The relevant code is in crypo/tls/handshake_server.go

        ok := false
        for _, ku := range certs[0].ExtKeyUsage {
            if ku == x509.ExtKeyUsageClientAuth {
                ok = true
                break
            }
        }
        if !ok {
            c.sendAlert(alertHandshakeFailure)
            return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication")
        }

I think Go is making a mistake in assuming that client certificates
without the extended usage attributes (ie most client certificates)
should be denied use as a client authentication.

So removing this code would fix the problem or possibly Go should
assume certificates without the extended trust attributes should be
allowed rather than rejected.

From the OpenSSL docs

http://www.openssl.org/docs/apps/x509.html

> Trust settings currently are only used with a root CA. They allow a
> finer control over the purposes the root CA can be used for. For
> example a CA may be trusted for SSL client but not SSL server use.
>
> See the description of the verify utility for more information on
> the meaning of trust settings.
>
> Future versions of OpenSSL will recognize trust settings on any
> certificate: not just root CAs.

Indicating that OpenSSL doesn't use these trust settings at all
(confirmed with my experiments with Apache).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions