0
def cert_check(conn,cert,errnum,depth,ok):
    print 'Got cert',cert.get_subject()
    return ok

Server:

ctx = SSL.context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER,verify_cb)
ctx.use_private_key_file('server.key')
ctx.use_certificate_file('server.crt')
ctx.load_verify_locations('ca.crt')

Client:

ctx = SSL.context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER,verify_cb)
ctx.use_private_key_file('client.key')
ctx.use_certificate_file('client.crt')
ctx.load_verify_locations('ca.crt')

How is it that on both client and server side, I get two certificates. One with no CommonName and one with the correct CommonName= myownserver.com/myownclient.com

All the aforementioned files have just one key/certificate. Also, I am guessing that the first printed certificate is the ca.crt because it is the only certificate without any CommonName. But why would that happen?

Lelouch Lamperouge
  • 8,171
  • 8
  • 49
  • 60

2 Answers2

0

The accepted answer is not exactly informative but is close enough to be vaguely related..

First of all, the value of verify_cb in set_verify is a typo as cert_check seems to be the appropriate function signature therefore the question revise is:

def cert_check(conn,cert,errnum,depth,ok):
    print 'Got cert',cert.get_subject()
    return ok

Server:

ctx = SSL.context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER,cert_check)
ctx.use_private_key_file('server.key')
ctx.use_certificate_file('server.crt')
ctx.load_verify_locations('ca.crt')

Client:

ctx = SSL.context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER,cert_check)
ctx.use_private_key_file('client.key')
ctx.use_certificate_file('client.crt')
ctx.load_verify_locations('ca.crt')

How is it that on both client and server side, I get two certificates. One with no CommonName and one with the correct CommonName= myownserver.com/myownclient.com

The explanation of what is happening with set_verify can be reviewed here; Can someone explain this callback function for SSL certificates?

As a debug tip, you can view the cert with

print(dump_certificate(FILETYPE_TEXT, cert).decode())

To answer the direct question:

a) The server received a client certificate, because it was provided by the client to the server

b) The server will already have a root store; trusted root CA certificates. The second certificate you see in the server context of the connection will be the root CA cert that matches the client cert issuer CA (if the CA is in the cert store)

c) The client context will have all peer certificates, not only 2. Typically a server chain is 3 or more;

  • root CA - in the client device root store)
  • singing CA cert - the company you paid when you purchased a cert for your server, this CA has a cert in the chain that represents an authority given to them by the trusted root CA, so they can sign certificates for customers like you
  • server cert - the certificate you purchased and installed in your webserver config

d) the fact there was 2 certs in your client context indicates to me a strong possibility that you self-signed. This would mean the intermediate authority is not a CA and also not likely trusted by a root CA but you signed a certificate for your server anyway:

  • intermediate is the self-signed root certificate used to sign server certificates. it will not have a trusted root CA so the client context will not pull one out of your trust store to complete a typical chain of 3, resulting in only 2 certs in your chain
  • server cert which is self-signed

e) As the question has indicated a successful tls negotiation, and that there were 2 certs on the server context, this indicates to me that the self-signed cert was added to your server trusted root store. this can happen in many methods but the runtime method using the question specific library pyOpenSSL would be ctx.load_verify_locations(cafile) as the most likely place the self-signed certificate was added to the trusted root store on the server

Stof
  • 610
  • 7
  • 16
-1

This depends on the depth that has been set for verification.

From the man pages the maximum depth for the certificate chain verification that shall be allowed for the current context. Also, depth's default value is 9.

Lelouch Lamperouge
  • 8,171
  • 8
  • 49
  • 60