Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ssl server: how to disable client cert verfication?

673 views
Skip to first unread message

Grant Edwards

unread,
Feb 3, 2022, 1:58:52 PM2/3/22
to
I've got a small ssl server app. I want to require a certificate from
the client, so I'm using a context with

context.verify_mode = ssl.CERT_REQUIRED

But, I want all certificates accepted. How do I disable client
certificate verification?

--
Grant



Kushal Kumaran

unread,
Feb 3, 2022, 2:39:15 PM2/3/22
to
Perhaps you can explain what your goal is. Which kinds of client
certificates do you want to permit (to the best of my knowledge, none of
these can be actually allowed):

- expired certificates

- self-signed certificates

- certificates signed by untrusted CA

- completely garbage certificates (bad signature, etc.)

I don't see what benefit you expect from requiring client certificates
if you don't care what the certificate says. Why not simply set
verify_mode to SSL_NONE and use other authentication mechanisms?

--
regards,
kushal

Grant Edwards

unread,
Feb 3, 2022, 4:33:02 PM2/3/22
to
On 2022-02-03, Kushal Kumaran <kus...@locationd.net> wrote:

> On Thu, Feb 03 2022 at 10:57:56 AM, Grant Edwards <grant.b...@gmail.com> wrote:
>> I've got a small ssl server app. I want to require a certificate from
>> the client, so I'm using a context with
>>
>> context.verify_mode = ssl.CERT_REQUIRED
>>
>> But, I want all certificates accepted. How do I disable client
>> certificate verification?
>>
>
> Perhaps you can explain what your goal is.

It's a troubleshooting utility for displaying a client's certificate.

> Which kinds of client certificates do you want to permit

All of them. Anything that's parsable as an X509 certificate no matter
how "invalid" it is.

> (to the best of my knowledge, none of these can be actually allowed):
>
> - expired certificates
> - self-signed certificates
> - certificates signed by untrusted CA
> - completely garbage certificates (bad signature, etc.)
>
> I don't see what benefit you expect from requiring client
> certificates if you don't care what the certificate says.

I do care what it says. The whole point is to find out what it says.

I just don't want it validated by the SSL layer: I want to print it
out. That seems to be trivial to do for server certificates using
"openssl s_client", but I can't find any way to do it for client
certficates.

> Why not simply set verify_mode to SSL_NONE and use other
> authentication mechanisms?

I'm not interested in doing any authentication.

I just want to require that the client provide a certificate and then
print it out using print(connection.getpeercert())

--
Grant


Barry

unread,
Feb 3, 2022, 5:07:56 PM2/3/22
to


> On 3 Feb 2022, at 21:34, Grant Edwards <grant.b...@gmail.com> wrote:
I am not near the pc with the code on. But in outline you provide a ssl context that
returns true for the validation of the cert always. You also get to have x509 cert
in your hands. I use pyopenssl to play with x.509 certs.

Let me know if this is not enough info and I will dig out the code I have that
does this custom cert stuff.

Barry

>
> --
> Grant
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>

Grant Edwards

unread,
Feb 3, 2022, 5:37:17 PM2/3/22
to
On 2022-02-03, Barry <ba...@barrys-emacs.org> wrote:
>
>> [...] I just want to require that the client provide a certificate
>> and then print it out using print(connection.getpeercert())
>
> I am not near the pc with the code on. But in outline you provide a
> ssl context that returns true for the validation of the cert always.

I thought that was what I was asking.

How do you create an ssl context that requests a client certificate
but then treats any received client certificate as valid?

I've looked through the ssl.Context documentation multiple times, and
haven't been able to spot any option or flag that disables client
certificate validation or allows the user to override the actual
client certificate validation process.

> You also get to have x509 cert in your hands. I use pyopenssl to
> play with x.509 certs.

I don't have any problem getting and printing the certificate once the
connection is established. The problem is preventing the handshake
from failing when the client certificate isn't valid and signed by a
CA provided to the context with .load_verify_locations().

> Let me know if this is not enough info and I will dig out the code I
> have that does this custom cert stuff.

--
Grant

Chris Angelico

unread,
Feb 4, 2022, 1:23:59 AM2/4/22
to
On Fri, 4 Feb 2022 at 09:37, Grant Edwards <grant.b...@gmail.com> wrote:
> I've looked through the ssl.Context documentation multiple times, and
> haven't been able to spot any option or flag that disables client
> certificate validation or allows the user to override the actual
> client certificate validation process.

What you're doing is a little unusual, so my first thought would be to
subclass Context and override whatever method does the checks.

ChrisA

Kushal Kumaran

unread,
Feb 4, 2022, 1:24:00 AM2/4/22
to
On Thu, Feb 03 2022 at 01:32:04 PM, Grant Edwards <grant.b...@gmail.com> wrote:
> On 2022-02-03, Kushal Kumaran <kus...@locationd.net> wrote:
>
>> On Thu, Feb 03 2022 at 10:57:56 AM, Grant Edwards <grant.b...@gmail.com> wrote:
>>> I've got a small ssl server app. I want to require a certificate from
>>> the client, so I'm using a context with
>>>
>>> context.verify_mode = ssl.CERT_REQUIRED
>>>
>>> But, I want all certificates accepted. How do I disable client
>>> certificate verification?
>>>
>>
>> Perhaps you can explain what your goal is.
>
> It's a troubleshooting utility for displaying a client's certificate.
>
>> Which kinds of client certificates do you want to permit
>
> All of them. Anything that's parsable as an X509 certificate no matter
> how "invalid" it is.
>

Does `openssl x509 -in <filename> -text -noout` do what you want?

>> (to the best of my knowledge, none of these can be actually allowed):
>>
>> - expired certificates
>> - self-signed certificates
>> - certificates signed by untrusted CA
>> - completely garbage certificates (bad signature, etc.)
>>
>> I don't see what benefit you expect from requiring client
>> certificates if you don't care what the certificate says.
>
> I do care what it says. The whole point is to find out what it says.
>
> I just don't want it validated by the SSL layer: I want to print it
> out. That seems to be trivial to do for server certificates using
> "openssl s_client", but I can't find any way to do it for client
> certficates.
>

In your place, I would simply use the openssl x509 command. If I wanted
more/different info, I would write a script to load the certificate and
printed out the relevant info. If this functionality must be provided
by a server, I would write it so that a certificate could be POSTed to
the server (without using client certificates), and it would in turn do
the parsing equivalent to what the standalone script would do and
respond with the relevant info. (But I hear X.509 parsing is an
esoteric mess, and it's unclear to me what demons lie in the area of
parsing untrusted X.509 content).

I don't know how to use the stdlib's ssl module to do this kind of
parsing. The cryptography package makes this simple though:

https://cryptography.io/en/latest/x509/reference/#loading-certificates

>> Why not simply set verify_mode to SSL_NONE and use other
>> authentication mechanisms?
>
> I'm not interested in doing any authentication.
>
> I just want to require that the client provide a certificate and then
> print it out using print(connection.getpeercert())
>

--
regards,
kushal

Grant Edwards

unread,
Feb 4, 2022, 1:16:03 PM2/4/22
to
I've done a dir() on the Context object, and I don't see anything that
looks like a method to do the checks. I suspect that the Context
object doesn't actually _do_ anything, it just hold a reference to an
underlying openssl context object and allow to to change its
configuration values.

--
Grant


Grant Edwards

unread,
Feb 4, 2022, 1:25:35 PM2/4/22
to
On 2022-02-04, Kushal Kumaran <kus...@locationd.net> wrote:

>> It's a troubleshooting utility for displaying a client's certificate.
>>
>>> Which kinds of client certificates do you want to permit
>>
>> All of them. Anything that's parsable as an X509 certificate no matter
>> how "invalid" it is.
>>
>
> Does `openssl x509 -in <filename> -text -noout` do what you want?

Where does <filename> come from?

>> I just don't want it validated by the SSL layer: I want to print it
>> out. That seems to be trivial to do for server certificates using
>> "openssl s_client", but I can't find any way to do it for client
>> certficates.
>
> In your place, I would simply use the openssl x509 command.

How does the x509 command obtain the certificate from the
client/server handshake?

> If I wanted more/different info, I would write a script to load the
> certificate and printed out the relevant info.

How does one "load the certificate" from the client?

> If this functionality must be provided by a server,

> I would write it so that a certificate could be POSTed to
> the server (without using client certificates),

The problem is in getting the certificate is provided by the client
during the handshake with the server. Don't worry about how to
parse/print it -- I can deal with that.

> I don't know how to use the stdlib's ssl module to do this kind of
> parsing.

I'm not asking about parsing x509 certificates. That's not the
problem.

The problem is _getting_ the client certificate that was provided
during the client/server handshake. That's trivial if the handshake
was successful. The problem is obtaining the client certificate when
the handshake fails. I was hoping there was a way to disable client
certificate validation so that the handshake will succeed and then
allow me to get the client certificate from the connection object.

--
Grant



Barry

unread,
Feb 4, 2022, 1:36:17 PM2/4/22
to


> On 4 Feb 2022, at 18:17, Grant Edwards <grant.b...@gmail.com> wrote:
We started with the OpenSSL api and looked see what it provided.
Then looked for how to access that from python.

Christian Heimes

unread,
Feb 4, 2022, 1:59:49 PM2/4/22
to
On 03/02/2022 19.57, Grant Edwards wrote:
> I've got a small ssl server app. I want to require a certificate from
> the client, so I'm using a context with
>
> context.verify_mode = ssl.CERT_REQUIRED
>
> But, I want all certificates accepted. How do I disable client
> certificate verification?

You can't. Python's ssl module does not expose the necessary feature to
override the verification callback SSL_CTX_set_verify(). PyOpenSSL lets
you set a callback and ignore any and all errors.

Christian

Christian Heimes

unread,
Feb 4, 2022, 2:02:47 PM2/4/22
to
On 04/02/2022 19.24, Grant Edwards wrote:
> The problem is _getting_ the client certificate that was provided
> during the client/server handshake. That's trivial if the handshake
> was successful. The problem is obtaining the client certificate when
> the handshake fails. I was hoping there was a way to disable client
> certificate validation so that the handshake will succeed and then
> allow me to get the client certificate from the connection object.

FYI, it's more complicated in TLS 1.3. Post-handshake authentication
(PHA) can happen out-of-bounce. Only TLS 1.2 performs client cert auth
during handshake or renegotiation.

Christian

Dieter Maurer

unread,
Feb 4, 2022, 2:28:55 PM2/4/22
to
Grant Edwards wrote at 2022-2-3 14:36 -0800:
>On 2022-02-03, Barry <ba...@barrys-emacs.org> wrote:
> ...
>I've looked through the ssl.Context documentation multiple times, and
>haven't been able to spot any option or flag that disables client
>certificate validation or allows the user to override the actual
>client certificate validation process.

Note that Python does not do the certificate validation itself
but delegates this to the underlying SSL library.
Thus, this library would need to support your use case.
It may not as your scenario is quite special.

Grant Edwards

unread,
Feb 4, 2022, 2:41:24 PM2/4/22
to
That's fine. I can force TLS 1.2 to be used. I don't think there are
going to be situations where the choice of 1.2 vs 1.3 will affect what
certificate is supplied by the client.

The 1.3 PHA would also be OK as long as

1. I can disable verification of the client certificate that's
obtained via PHA.

2. I can obtain the client certificated that was sent during PHA.

What's odd is that it's trivial to do what I want from the client side
using "openssl s_client", but there doesn't seem to be any way to do
the corresponding using "openssl s_server".

I'm beginning to suspect this is a deficiency in the openssl library
itself.

--
Grant


Grant Edwards

unread,
Feb 4, 2022, 2:43:14 PM2/4/22
to
On 2022-02-04, Barry <ba...@barrys-emacs.org> wrote:
>>
>>> What you're doing is a little unusual, so my first thought would be to
>>> subclass Context and override whatever method does the checks.
>>
>> I've done a dir() on the Context object, and I don't see anything that
>> looks like a method to do the checks. I suspect that the Context
>> object doesn't actually _do_ anything, it just hold a reference to an
>> underlying openssl context object and allow to to change its
>> configuration values.
>
> We started with the OpenSSL api and looked see what it provided.
> Then looked for how to access that from python.

Right. I now suspect this is something missing from the oponssl server
side library code. It's trivial to do the same thing from the client
side (ignore the validity of the server certificate).

--
Grant



Grant Edwards

unread,
Feb 4, 2022, 2:44:26 PM2/4/22
to
On 2022-02-04, Christian Heimes <chri...@python.org> wrote:
Thanks! I'll look into that.

Since "openssl s_client" didn't seem to have any option to ignore
client cert validity, I was starting to wonder if ignoring it was
simply impossible with openssl.

--
Grant



Grant Edwards

unread,
Feb 4, 2022, 2:47:09 PM2/4/22
to
The corresponding scenario is easily supported for the client
side. Even "openssl s_client" offers the option to ignore cert
validation failures and print the cert anyway. It seems odd that
s_server can't do the same.

--
Grant

0 new messages