Bug #3640

Added CRL disable option

Added by Ohad Levy almost 2 years ago. Updated over 1 year ago.

Status:Closed Start date:04/21/2010
Priority:Normal Due date:
Assignee:Ohad Levy % Done:

0%

Category:SSL
Target version:0.25.5
Affected Puppet version:0.25.5rc1 Branch:
Keywords:
Votes: 0

Description

Hi,

it seems that 0.25.x SSL is broken when using a chained CA.

I’m attaching a simple script (and output) showing that using simple net/https works, while using puppet internally does not.

it doesn’t seems to be related to the SSL initialization itself, rather to something else

h2. example script

require 'net/https'
require 'puppet/network/http_pool'

args = ["puppet", 8140]
header = { "Accept" => "pson" }
url = "/development/file_content/facts/somefact.rb"


http = Puppet::Network::HttpPool.http_instance(*args)
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
begin
  puts http.get url, header
rescue 
 warn $!
end

Puppet[:config] = "/etc/puppet/puppet.conf"
Puppet.parse_config
http = Net::HTTP.new(*args)
http.use_ssl = true
http.cert_store = OpenSSL::X509::Store.new
http.key = OpenSSL::PKey::RSA.new(File::read(Puppet[:hostprivkey]))
http.cert = OpenSSL::X509::Certificate.new(File::read(Puppet[:hostcert]))
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ca_file = Puppet[:localcacert]

puts http.get url, header

h2. output

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
#
"#"

Related issues

related to Puppet - Bug #3360: Add a flag to make puppet ca behavior on receipt of dupli... Closed 03/09/2010
related to Puppet - Bug #3450: Revert #2890 due to design / implementation problems Closed 03/29/2010
related to Puppet - Bug #3120: 'localcacert' doesn't behave as described Needs Decision 01/27/2010
related to Puppet - Bug #3143: Puppet should correctly support CA trust chains Accepted 02/03/2010
related to Puppet - Bug #3168: Cannot disable use of CRL in puppetd Investigating 02/06/2010
related to Puppet - Bug #1418: Puppetmasters don't honor cert revocation list Closed 07/12/2008
precedes Puppet - Bug #3770: Puppet SSL verfication is broken with multiple chained ce... Accepted 04/22/2010 04/22/2010

History

Updated by Ohad Levy almost 2 years ago

Further investigation (with the help of Brice) shows that my example code doesn’t contain the CRL verifications.

removing the CRL verification from the client seems to be “solving” the issue. e.g.:

diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb
index 9d016c8..ebe170a 100644
--- a/lib/puppet/ssl/host.rb
+++ b/lib/puppet/ssl/host.rb
@@ -213,7 +213,7 @@ class Puppet::SSL::Host
 
             # If there's a CRL, add it to our store.
             if crl = Puppet::SSL::CertificateRevocationList.find("ca")
-                @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
+#                @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
                 @ssl_store.add_crl(crl.content)
             end
             return @ssl_store

if I understand correctly, one can split the problem into a few parts:

  1. CRL will always be generated on each and every CA.
  2. CRL will be pushed to the client (if none exits) – but will not be updated anymore (regardless of changes to it)

may I suggest that: 1. CRL verification should be configurable on the client. 2. CRL source may be another CA server (e.g. upstream CA server) 3. CRL on the client should be re-synced every interval 4. Master CA will not auto generate a CRL (or at-least allow to configure it) 5. consider switching to OCSP.

Updated by Markus Roberts almost 2 years ago

  • Status changed from Unreviewed to Investigating

Updated by Markus Roberts almost 2 years ago

On further investigation it appears that the problem may be that the flag settings are incorrect. There was an OpenSSL bug many years ago (openssl <= 0.9.7a) in which the flags were reversed, and the conjunction was used as a workaround for this bug.

It appears (though I have not verified this) that the combination hack fails to work as expected on newer (>= 0.9.8) versions. While we may ultimately have to set the flags based on the openssl version, it may be that OR-ing in the flag we want will suffice:

diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb
index 9d016c8..ebe170a 100644
--- a/lib/puppet/ssl/host.rb
+++ b/lib/puppet/ssl/host.rb
@@ -213,7 +213,7 @@ class Puppet::SSL::Host

             # If there's a CRL, add it to our store.
             if crl = Puppet::SSL::CertificateRevocationList.find("ca")
-                @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
+                @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
                 @ssl_store.add_crl(crl.content)
             end
             return @ssl_store

Can you try this, and report back:

  1. If it works
  2. If CRLs still work
  3. The version of openssl you tested on

In the meantime, I’ll continue to investigate.

— Markus

Updated by Markus Roberts almost 2 years ago

The openssl change log may prove to be a useful resource if we wind up having to do something version sensitive:

http://www.openssl.org/source/exp/CHANGES

Updated by Markus Roberts almost 2 years ago

Looking at the code for openssl 0.9.8k, it appears we may also need to define:

V_FLAG_ALLOW_PROXY_CERTS = 0x40

And write:

@ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK|V_FLAG_ALLOW_PROXY_CERTS

although this is not what I would characterize as “obvious” and I’d like to find some support for it from the documentation.

— Markus

P.S. It is possible (though not as likely) that the correct combination is all three: check, check_all, and allow_proxy_certs, though I’m even more dubious of that path).

Updated by Luke Kanies almost 2 years ago

I’ve put up a simple branch that disables the CRL for both new and old SSL:

luke/tickets/0.25.x/3640-disable_certificate_revocation

I had to disable it in the old SSL code because the CA handler was automatically creating it.

This is at least a hack fix.

Updated by Markus Roberts almost 2 years ago

I didn’t see Luke’s patch on the list, so I’ll respond here: +1 as a stopgap for 0.25.5, provided it works for Ohad, but I’d like to see a real solution for Rowlf and/or 0.25.6

Updated by Markus Roberts almost 2 years ago

  • Status changed from Investigating to Accepted

Apparently (based on his email) none of the above worked for Ohad. Also, we have uncovered a number of other, closely related issues. I’m marking the ticket accepted and will be working over the next 12 hours or so to set a target version. If we can devise a simple / straightforward fix that works in the field, we’ll float it in a 0.25.5rc3; if not, we’ll go ahead with rc2 and target this at 0.25.6, with bells on it.

Updated by Markus Roberts almost 2 years ago

  • Status changed from Accepted to Needs More Information
  • Assignee set to Ohad Levy

Ohad —

Re-reading the ticket for the Nth time, something struck me. You say:

I'm attaching a simple script (and output) showing that using simple net/https works, while using puppet internally does not.

but the output you attached shows it failing, not working:

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
#
"#" 

My reading of this is that the certificate verification failed, but you went ahead and used it anyway (the equivalent of clicking “use it anyway” on the “I’m feeling luck/trusting/gullible” pop-up in a browser. In other words, your script appears to show that it’s not just puppet that’s objecting to the cert.

Agree? Disagree? Thoughts?

— Markus

P.S. On the (N+2)th reading, it appears that I’d missed the fact that there were two calls, and the first used

http = Puppet::Network::HttpPool.http_instance(*args)

so (depending on which lines are produced by which call) it might be failing in the puppet form and working when called directly, as you suggest.

Updated by Markus Roberts over 1 year ago

In the my comment, the P.S. appears to have been correct and the body just an example of why I generally drink coffee before programming, instead of just starting typing away.

— Markus

Updated by Ohad Levy over 1 year ago

as expected, Luke’s patch is working http://github.com/lak/puppet/commit/bb07664e22ef7c035576e25c8ed699990365626d

I took an existing 0.24.8 client, upgrade it to 0.25.5 and got the client working fine.

however, when I’m trying to use the 0.25.5 master to sign a new ca, it fails. it seems, that puppet is really unhappy if the certs/ca.pem file contain other certificates. afaik, this is the place to put the top level ca pub key, however, the puppetmaster keeps replacing the content of this file to match to the local ca pub key (ca/ca_crt.pem) from the log:

Removing file Puppet::SSL::Certificate ca at '/var/lib/puppet/ssl/certs/ca.pem'
Retrieved certificate does not match private key
Signed certificate request for ca
Starting Puppet server version 0.25.5

Updated by Luke Kanies over 1 year ago

What if the top-level CA has all of the certs in it?

At this point, I really don’t think we can fix chained certs in this release.

I think we cut 0.25.5 as soon as the yaml thing is fixed, and then we focus on a new release with chained certs working.

We should be able to get a patch working relatively quickly once the release is out, but given how we keep finding little things, we should not hold the release up for this.

Updated by James Turnbull over 1 year ago

  • Status changed from Needs More Information to Closed
  • Target version set to 0.25.5

Partial fix pushed in commit:92144000683cf596693596bf653bbd7e089976ef in branch 0.25.x

Updated by James Turnbull over 1 year ago

  • Subject changed from Puppet SSL verfication is broken with multiple chained certificates to Added CRL disable option

Also available in: Atom PDF