Bug #4948

connecting from a client whose cert is revoked fails without indicating why

Added by eric sorenson over 1 year ago. Updated 4 months ago.

Status:Accepted Start date:10/06/2010
Priority:High Due date:
Assignee:- % Done:

0%

Category:SSL
Target version:2.7.x
Affected Puppet version:0.25.0 Branch:
Keywords:CRL
Votes: 1

Description

had a confusing time tonight trying to debug some systems which were failing puppetd -tv — the error output looked like:


[root@it11p00me-acctsvc001 /var/lib/puppet]# puppetd -tv
info: Retrieving plugin
err: /File[/var/lib/puppet/lib]: Failed to generate additional resources using 'eval_generate': certificate verify failed
err: /File[/var/lib/puppet/lib]: Failed to retrieve current state of resource: certificate verify failed Could not retrieve file metadata for
 puppet://puppet/plugins: certificate verify failed
info: Loading facts in locallinks
info: Loading facts in locallinks
err: Could not retrieve catalog from remote server: certificate verify failed
warning: Not using cache on failed catalog
err: Could not retrieve catalog; skipping run

The cause was that the cert’s serial number was in the CRL downloaded from the CA – probably due to a misunderstanding on my part of how exactly to issue new certificates to hosts whose private keys are lost due to re-imaging.

But regardless it would be nice to emit some kind of informative error message if we find out the local certificate is in the CA’s CRL.

History

Updated by Jeff McCune over 1 year ago

Unfortunately these error messages come from the openssl ruby layer itself rather than puppet and it’s extremely difficult for puppet to determine why a certificate verification check failed in the openssl layer.

Updated by Markus Roberts over 1 year ago

  • Category set to SSL
  • Status changed from Unreviewed to Accepted
  • Target version set to 2.7.x
  • Affected Puppet version set to 0.25.0

Yet another argument for using the client tools rather than the API wrapper from mars. :)

Updated by eric sorenson over 1 year ago

The same error cuts both ways apparently. We had issued a small number (~10) of certificates with overlapping serial numbers and revoked some of them as hosts were reimaged.

One of the revoked serial numbers belonged to a host and the certificate for the ‘puppet.mydomain.com’ VIP. So when clients downloaded the CRL, they stopped trusting the VIP.

This was only discoverable through packet analysis: (10.1.1.1 is the client, 10.2.2.2 is the VIP fronting the puppetmaster)

[root@host ~]# tshark -s1500 -i eth0 -n -d tcp.port==8140,ssl port 8140
  0.000000 10.1.1.1 -> 10.2.2.2 TCP 51532 > 8140 [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=3705949461 TSER=0 WS=7
  0.000527 10.2.2.2 -> 10.1.1.1 TCP 8140 > 51532 [SYN, ACK] Seq=0 Ack=1 Win=8190 Len=0 MSS=1460
  0.000543 10.1.1.1 -> 10.2.2.2 TCP 51532 > 8140 [ACK] Seq=1 Ack=1 Win=5840 Len=0
  0.000981 10.1.1.1 -> 10.2.2.2 SSLv2 Client Hello
  0.001640 10.2.2.2 -> 10.1.1.1 TLSv1 Server Hello, Certificate, Certificate Request, Server Hello Done
  0.001670 10.1.1.1 -> 10.2.2.2 TCP 51532 > 8140 [ACK] Seq=106 Ack=1358 Win=8142 Len=0
  0.002009 10.1.1.1 -> 10.2.2.2 TLSv1 Alert (Level: Fatal, Description: Certificate Revoked)

Updated by Brice Figureau over 1 year ago

Jeff McCune wrote:

Unfortunately these error messages come from the openssl ruby layer itself rather than puppet and it’s extremely difficult for puppet to determine why a certificate verification check failed in the openssl layer.

I don’t think it’s right. You can define a verify_callback on any ssl context (and this can be done with Net::HTTPS too). This proc will be called after validation is done and you can ask the context for more information about the error.

The question is: isn’t it an information disclosure to let the client know his cert has been revoked?

Updated by eric sorenson over 1 year ago

Brice Figureau wrote:

The question is: isn’t it an information disclosure to let the client know his cert has been revoked?

I don’t think so, because “Cert Revoked” is an explicit message type during TLS negotiation, so a client would see the revocation error just by running verbose openssl negotiation.

http://en.wikipedia.org/wiki/Transport_Layer_Security#Alert_protocol

Updated by Brice Figureau over 1 year ago

eric sorenson wrote:

Brice Figureau wrote:

The question is: isn’t it an information disclosure to let the client know his cert has been revoked?

I don’t think so, because “Cert Revoked” is an explicit message type during TLS negotiation, so a client would see the revocation error just by running verbose openssl negotiation.

http://en.wikipedia.org/wiki/Transport_Layer_Security#Alert_protocol

Then +1 for this bug.

Updated by Brice Figureau over 1 year ago

Brice Figureau wrote:

eric sorenson wrote:

Brice Figureau wrote:

The question is: isn’t it an information disclosure to let the client know his cert has been revoked?

I don’t think so, because “Cert Revoked” is an explicit message type during TLS negotiation, so a client would see the revocation error just by running verbose openssl negotiation.

http://en.wikipedia.org/wiki/Transport_Layer_Security#Alert_protocol

Then +1 for this bug.

I’m afraid it won’t be fixed because of #4273 Maybe if we only display the extended error message it will work? (and log it at a level > debug to be useful).

Updated by eric sorenson about 1 year ago

One more problem that can cause a very similar looking error and cause the client to completely fail, with the following message during the pluginsync phase:

err: /File[/var/lib/puppet/lib]: Failed to generate additional resources using 'eval_generate': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify fai
led
err: /File[/var/lib/puppet/lib]: Could not evaluate: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed Could not retrieve file metadata for pu
ppet://puppet/plugins: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

This happened because the CRL downloaded from the server has an issuer field that does not match the Subject field of CA.pem. You can tell with the following command:

# good
openssl crl -noout -CAfile certs/ca.pem -in crl.pem 
verify OK
# bad
openssl crl -noout -CAfile certs/ca.pem -in crl-fatal.pem 
Error getting CRL issuer certificate

In my case this happened because I had converted this puppetmaster from a standalone CA to using my site-wide CA certificate, but ‘puppet cert’ reused the Issuer field it found in ‘$ssldir/crl.pem’ (which had been created along with the original CA certificate) instead of the cleaned/cloned ‘$ssldir/ca/ca_crl.pem’ i.e. it used :hostcrl instead of :cacrl.

Updated by James Turnbull 9 months ago

  • Keywords set to CRL

Updated by Daniel Pittman 8 months ago

http://www.braintreepayments.com/devblog/sslsocket-verify_mode-doesnt-verify demonstrates the mechanism for extracting the error message and turning it into a more useful exception. We should do that.

Updated by James Turnbull 7 months ago

  • Status changed from Accepted to Needs Decision
  • Assignee set to Nigel Kersten

Thoughts on Daniel’s suggestion?

Updated by eric sorenson 7 months ago

FWIW this happened to another team here last week. It took out their SSL setup for a couple of days until they grew frustrated with debugging and came ‘round to ask me if I’d seen it before.

Updated by Nigel Kersten 6 months ago

  • Status changed from Needs Decision to Accepted
  • Assignee deleted (Nigel Kersten)
  • Priority changed from Normal to High
  • Target version changed from 2.7.x to 3.x

Updated by Nigel Kersten 6 months ago

  • Target version changed from 3.x to 2.7.x

eek. This is supposed to stay at 2.7.x

Also available in: Atom PDF