diff options
author | danielsdeleo <dan@opscode.com> | 2013-10-17 12:52:19 -0700 |
---|---|---|
committer | danielsdeleo <dan@opscode.com> | 2013-10-17 14:03:53 -0700 |
commit | 12e5661a0f54cf6edd0d62a62bee0c65e6f4ec2b (patch) | |
tree | 5d7b3cd791a533b52c385c3df578c917a9871b2c | |
parent | d3574a1e3e15bf8facb8efa6d44d2d287731d1ea (diff) | |
download | chef-12e5661a0f54cf6edd0d62a62bee0c65e6f4ec2b.tar.gz |
Add a directory where trusted certs can be stored
-rw-r--r-- | lib/chef/config.rb | 9 | ||||
-rw-r--r-- | lib/chef/http/basic_client.rb | 3 | ||||
-rw-r--r-- | lib/chef/http/ssl_policies.rb | 15 | ||||
-rw-r--r-- | spec/data/trusted_certs/example.crt | 22 | ||||
-rw-r--r-- | spec/data/trusted_certs/intermediate.pem | 27 | ||||
-rw-r--r-- | spec/data/trusted_certs/opscode.pem | 38 | ||||
-rw-r--r-- | spec/data/trusted_certs/root.pem | 22 | ||||
-rw-r--r-- | spec/unit/http/ssl_policies_spec.rb | 28 |
8 files changed, 163 insertions, 1 deletions
diff --git a/lib/chef/config.rb b/lib/chef/config.rb index 70cf3834b6..feb7e4ea94 100644 --- a/lib/chef/config.rb +++ b/lib/chef/config.rb @@ -103,7 +103,7 @@ class Chef if local_mode path_join(user_home, ".chef#{platform_path_separator}") else - ::File.dirname(config_file) + config_file && ::File.dirname(config_file) end end @@ -354,9 +354,16 @@ class Chef # regardless of the :ssl_verify_mode setting. default :verify_api_cert, false + # Path to the default CA bundle files. default :ssl_ca_path, nil default :ssl_ca_file, nil + # A directory that contains additional SSL certificates to trust. Any + # certificates in this directory will be added to whatever CA bundle ruby + # is using. Use this to add self-signed certs for your Chef Server or local + # HTTP file servers. + default(:trusted_certs_dir) { config_dir && path_join(config_dir, "trusted_certs") } + # Where should chef-solo download recipes from? default :recipe_url, nil diff --git a/lib/chef/http/basic_client.rb b/lib/chef/http/basic_client.rb index fb28a841c8..5ee0fbf88d 100644 --- a/lib/chef/http/basic_client.rb +++ b/lib/chef/http/basic_client.rb @@ -63,6 +63,9 @@ class Chef # force the issue: return [http_request, response] end + rescue OpenSSL::SSL::SSLError => e + Chef::Log.error("SSL Validation failure connecting to host: #{host} - #{e.message}") + raise end #adapted from buildr/lib/buildr/core/transports.rb diff --git a/lib/chef/http/ssl_policies.rb b/lib/chef/http/ssl_policies.rb index 00adcaca1c..17b46a6762 100644 --- a/lib/chef/http/ssl_policies.rb +++ b/lib/chef/http/ssl_policies.rb @@ -44,6 +44,7 @@ class Chef def apply set_verify_mode set_ca_store + set_custom_certs set_client_credentials end @@ -69,6 +70,20 @@ class Chef end end + def set_custom_certs + unless http_client.cert_store + http_client.cert_store = OpenSSL::X509::Store.new + http_client.cert_store.set_default_paths + end + if config.trusted_certs_dir + certs = Dir.glob(File.join(config.trusted_certs_dir, "*.{crt,pem}")) + certs.each do |cert_file| + cert = OpenSSL::X509::Certificate.new(File.read(cert_file)) + http_client.cert_store.add_cert(cert) + end + end + end + def set_client_credentials if (config[:ssl_client_cert] || config[:ssl_client_key]) unless (config[:ssl_client_cert] && config[:ssl_client_key]) diff --git a/spec/data/trusted_certs/example.crt b/spec/data/trusted_certs/example.crt new file mode 100644 index 0000000000..832aebe2ec --- /dev/null +++ b/spec/data/trusted_certs/example.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkjCCAnoCCQDihI8kxGYTFTANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMRAwDgYDVQQKEwdZb3VD +b3JwMRMwEQYDVQQLEwpPcGVyYXRpb25zMRYwFAYDVQQDEw1leGFtcGxlLmxvY2Fs +MR0wGwYJKoZIhvcNAQkBFg5tZUBleGFtcGxlLmNvbTAeFw0xMzEwMTcxODAxMzVa +Fw0yMzEwMTUxODAxMzVaMIGKMQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAO +BgNVBAcTB1NlYXR0bGUxEDAOBgNVBAoTB1lvdUNvcnAxEzARBgNVBAsTCk9wZXJh +dGlvbnMxFjAUBgNVBAMTDWV4YW1wbGUubG9jYWwxHTAbBgkqhkiG9w0BCQEWDm1l +QGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyKBo +U+Bdni0xZK/NCzdLdi2X+TyW5eahbYMx+r1GDcVqCICvrthBCVLVFsQ8rvOHwTPi +AxQJGxb9TLSXRgXQSlH6FLjIUceuOtpan3qYVJ1v7AxY4DgNvYBpbtJz5MQedJnT +g2F+rXzkwaD6CWBqWHeGU0oP3r7bq1AMD6XEsK2w2/zHtG7TEnL45ARv1PsyrU5M +ZAW/XyoMyq1k2Lpv7YR5kAvTq1+4RSt/it2RFE7R0AVbaQ0MeAnllfySiHHHlaOT +FVd/qPSiGISxsUmmzA3Z08+0sfJwkrnJXbLscCBYndd7gMGgtczGjJtul0Ch3GFa +/Pn5McjwF272+usJ1wIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCzPePWifWNECsG +nL8on1AtFMkczE1/pdRS4YUl/Tc926MpezptSja8rL31+4Bom37/wYPG7HygtAQl +R4FHpAtuqJKPOfjUmDNsIXRFnytrnflTpctDu/Nbj4PDCy01k/sTDUQt+s+lEBL8 +M8ArmfLZ8PCfAwnXmJQ5rggDFKqegjt6z1RsSglbMiASE7+KkpBnzaqH6fET6IQz +WgAjv6WdRfwgfJjOTSX4XMpCSet9KaWmXExKrxiVng2Uu6E+ShVAyKaGMuc1B7VA +oxnnVaVapFv5lOWucQr4KkC7EgaUZnyt8duOc8+Yvd+y3Xd2dcHUnmegRxly4jRV +/lXbFAUb +-----END CERTIFICATE----- diff --git a/spec/data/trusted_certs/intermediate.pem b/spec/data/trusted_certs/intermediate.pem new file mode 100644 index 0000000000..78148b0fcf --- /dev/null +++ b/spec/data/trusted_certs/intermediate.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjzCCA3egAwIBAgIQBp4dt3/PHfupevXlyaJANzANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEgxCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxIjAgBgNVBAMTGURpZ2lDZXJ0IFNlY3Vy +ZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7V+Qh +qdWbYDd+jqFhf4HiGsJ1ZNmRUAvkNkQkbjDSm3on+sJqrmpwCTi5IArIZRBKiKwx +8tyS8mOhXYBjWYCSIxzm73ZKUDXJ2HE4ue3w5kKu0zgmeTD5IpTG26Y/QXiQ2N5c +fml9+JAVOtChoL76srIZodgr0c6/a91Jq6OS/rWryME+7gEA2KlEuEJziMNh9atK +gygK0tRJ+mqxzd9XLJTl4sqDX7e6YlwvaKXwwLn9K9HpH9gaYhW9/z2m98vv5ttl +LyU47PvmIGZYljQZ0hXOIdMkzNkUb9j+Vcfnb7YPGoxJvinyulqagSY3JG/XSBJs +Lln1nBi72fZo4t9FAgMBAAGjggFaMIIBVjASBgNVHRMBAf8ECDAGAQH/AgEAMA4G +A1UdDwEB/wQEAwIBhjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6 +Ly9vY3NwLmRpZ2ljZXJ0LmNvbTB7BgNVHR8EdDByMDegNaAzhjFodHRwOi8vY3Js +My5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3JsMDegNaAzhjFo +dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3Js +MD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k +aWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBSQcds363PI79zVHhK2NLorWqCmkjAf +BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTANBgkqhkiG9w0BAQUFAAOC +AQEAMM7RlVEArgYLoQ4CwBestn+PIPZAdXQczHixpE/q9NDEnaLegQcmH0CIUfAf +z7dMQJnQ9DxxmHOIlywZ126Ej6QfnFog41FcsMWemWpPyGn3EP9OrRnZyVizM64M +2ZYpnnGycGOjtpkWQh1l8/egHn3F1GUUsmKE1GxcCAzYbJMrtHZZitF//wPYwl24 +LyLWOPD2nGt9RuuZdPfrSg6ppgTre87wXGuYMVqYQOtpxAX0IKjKCDplbDgV9Vws +slXkLGtB8L5cRspKKaBIXiDSRf8F3jSvcEuBOeLKB1d8tjHcISnivpcOd5AUUUDh +v+PMGxmcJcqnBrJT3yOyzxIZow== +-----END CERTIFICATE----- diff --git a/spec/data/trusted_certs/opscode.pem b/spec/data/trusted_certs/opscode.pem new file mode 100644 index 0000000000..d7d211c9da --- /dev/null +++ b/spec/data/trusted_certs/opscode.pem @@ -0,0 +1,38 @@ +-----BEGIN CERTIFICATE----- +MIIGqjCCBZKgAwIBAgIQCJlQhNSTz1z3zHZb972KvDANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSIwIAYDVQQDExlE +aWdpQ2VydCBTZWN1cmUgU2VydmVyIENBMB4XDTEzMDQxMjAwMDAwMFoXDTE0MDYx +NjEyMDAwMFowYzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO +BgNVBAcTB1NlYXR0bGUxFTATBgNVBAoTDE9wc2NvZGUsIEluYzEWMBQGA1UEAwwN +Ki5vcHNjb2RlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+U +HLAzObPRlmchlkJ2JFeReJRPXj5F27HuX8SXT+5WhVGunQf1swjASJ0utk1x9wGT +f9tnF8fYiwJIqWJopaPiwzNw1cD6CnIfhM3z4T3EzLAWWu2ZhfuaQk9Z6jhItkm7 +upO4CsFq1xw7IjqOq09PCAklYC/Y/8Qq5Qj8VoTp0ldVv6hbqTNkezhWcKU/07si +jAX1O+DYN6dlVNezfl4Xt5ccsu8Mp0s92IMVYLgY6bpb1b91ez9+XBE1v7zjaR0V +EP7Ix9av/pXjqMqHgjlsg46UpLa30f4FEi2xmXpCBpOP94rCrT7g+u8UlIrJ/QK/ +/lHyKBpCm0R9ftDbppsCAwEAAaOCA3MwggNvMB8GA1UdIwQYMBaAFJBx2zfrc8jv +3NUeErY0uitaoKaSMB0GA1UdDgQWBBTdhCU7MvQblxtWHlfHG4jPUTuh5DBLBgNV +HREERDBCgg0qLm9wc2NvZGUuY29tggtvcHNjb2RlLmNvbYIQY29ycC5vcHNjb2Rl +LmNvbYISKi5jb3JwLm9wc2NvZGUuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE +FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwYQYDVR0fBFowWDAqoCigJoYkaHR0cDov +L2NybDMuZGlnaWNlcnQuY29tL3NzY2EtZzEuY3JsMCqgKKAmhiRodHRwOi8vY3Js +NC5kaWdpY2VydC5jb20vc3NjYS1nMS5jcmwwggHEBgNVHSAEggG7MIIBtzCCAbMG +CWCGSAGG/WwBATCCAaQwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQu +Y29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0wggFkBggrBgEFBQcCAjCCAVYeggFS +AEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABpAGYAaQBj +AGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBu +AGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQ +AFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQAeQAg +AEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0ACAAbABp +AGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwByAHAAbwBy +AGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBl +AC4weAYIKwYBBQUHAQEEbDBqMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp +Y2VydC5jb20wQgYIKwYBBQUHMAKGNmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv +bS9EaWdpQ2VydFNlY3VyZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqG +SIb3DQEBBQUAA4IBAQCNk1+7l+VlAZrKov7ugP7WuKS7IEUZRk8CVAFPtIrp+jFB +6W0ta1qMpYyItp5enTBCGOkTfPly06hZnFRQw3ZnkSsWDKIvCRks4kZt3oHLd3nO +G671JGRJI/qbs6F5l6c96kotlZkolYIPMhyK8Ex4LjMW6UrPWdpJrXTWPvLq4c85 +ZaN52yKu6tsLrBTPwPmK9t+zQ2drb1g8Eq9B+cuwD3Row6njsDQ1Ltry+KCnivki +E/ptgwyCkS4brkhjHMz5l5Co0KMsHylAb2XcBxFVFSl0aJIqK5Gr0nTlg26pNG7O +qxv6ncOHl3tmArETi36TQbTYvFc+6cNb8CqdWe95 +-----END CERTIFICATE----- diff --git a/spec/data/trusted_certs/root.pem b/spec/data/trusted_certs/root.pem new file mode 100644 index 0000000000..fd4341df26 --- /dev/null +++ b/spec/data/trusted_certs/root.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- diff --git a/spec/unit/http/ssl_policies_spec.rb b/spec/unit/http/ssl_policies_spec.rb index a15fd46164..c80f989180 100644 --- a/spec/unit/http/ssl_policies_spec.rb +++ b/spec/unit/http/ssl_policies_spec.rb @@ -112,6 +112,34 @@ describe "HTTP SSL Policy" do http_client.key.to_s.should == IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.key') end end + + context "when additional certs are located in the trusted_certs dir" do + let(:self_signed_crt_path) { File.join(CHEF_SPEC_DATA, "trusted_certs", "example.crt") } + let(:self_signed_crt) { OpenSSL::X509::Certificate.new(File.read(self_signed_crt_path)) } + + let(:additional_pem_path) { File.join(CHEF_SPEC_DATA, "trusted_certs", "opscode.pem") } + let(:additional_pem) { OpenSSL::X509::Certificate.new(File.read(additional_pem_path)) } + + before do + Chef::Config.trusted_certs_dir = File.join(CHEF_SPEC_DATA, "trusted_certs") + end + + it "enables verification of self-signed certificates" do + http_client.cert_store.verify(self_signed_crt).should be_true + end + + it "enables verification of cert chains" do + # This cert is signed by DigiCert so it would be valid in normal SSL usage. + # The chain goes: + # trusted root -> intermediate -> opscode.pem + # In this test, the intermediate has to be loaded and trusted in order + # for verification to work correctly. + # If the machine running the test doesn't have ruby SSL configured correctly, + # then the root cert also has to be loaded for the test to succeed. + # The system under test **SHOULD** do both of these things. + http_client.cert_store.verify(additional_pem).should be_true + end + end end describe Chef::HTTP::APISSLPolicy do |