forked from jnunemaker/httparty
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ssl_ca_file and ssl_ca_path options to allow SSL certificate veri…
…fication.
- Loading branch information
Showing
15 changed files
with
305 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/bin/sh | ||
set -e | ||
|
||
if [ -d "generated" ] ; then | ||
echo >&2 "error: 'generated' directory already exists. Delete it first." | ||
exit 1 | ||
fi | ||
|
||
mkdir generated | ||
|
||
# Generate the CA private key and certificate | ||
openssl req -batch -subj '/CN=INSECURE Test Certificate Authority' -newkey rsa:1024 -new -x509 -days 999999 -keyout generated/ca.key -nodes -out generated/ca.crt | ||
|
||
# Create symlinks for ssl_ca_path | ||
c_rehash generated | ||
|
||
# Generate the server private key and self-signed certificate | ||
openssl req -batch -subj '/CN=localhost' -newkey rsa:1024 -new -x509 -days 999999 -keyout generated/server.key -nodes -out generated/selfsigned.crt | ||
|
||
# Generate certificate signing request with bogus hostname | ||
openssl req -batch -subj '/CN=bogo' -new -days 999999 -key generated/server.key -nodes -out generated/bogushost.csr | ||
|
||
# Sign the certificate requests | ||
openssl x509 -CA generated/ca.crt -CAkey generated/ca.key -set_serial 1 -in generated/selfsigned.crt -out generated/server.crt -clrext -extfile openssl-exts.cnf -extensions cert | ||
openssl x509 -req -CA generated/ca.crt -CAkey generated/ca.key -set_serial 1 -in generated/bogushost.csr -out generated/bogushost.crt -clrext -extfile openssl-exts.cnf -extensions cert | ||
|
||
# Remove certificate signing requests | ||
rm -f generated/*.csr | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ca.crt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIICAzCCAWygAwIBAgIBATANBgkqhkiG9w0BAQUFADAuMSwwKgYDVQQDEyNJTlNF | ||
Q1VSRSBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMDA3MDkwMTU5MTda | ||
Fw0xMDA4MDgwMTU5MTdaMA8xDTALBgNVBAMTBGJvZ28wgZ8wDQYJKoZIhvcNAQEB | ||
BQADgY0AMIGJAoGBAKMU3pAeBZzKYcYF8eDIPvb9qYF8odH9ZK23IGn1T9D9Oxd0 | ||
2+IltkMJ0sOWpknp+kTzbAP0dammMNExt/YFuFqN4MenTMp87FFQAXSK0WhtjNcb | ||
Fl9gv4iThWedFVSq3qZs8c+ZTCrrC/A/ScGAH7g4C57Degci7SCdf4v97m7nAgMB | ||
AAGjUDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFMXuuqokuPcMMS7OFu0jeoGK | ||
oJsDMB8GA1UdIwQYMBaAFJYXkYdQ2afmGvLRN9YGOqrGK/MLMA0GCSqGSIb3DQEB | ||
BQUAA4GBAIPfOu+RadQpZlSaMg3m7t7wn3yPPp2yXtz6s98JqBvoTtZZ0f9JMG6z | ||
muVss0JmHPTyPDlNk54DaySa0wAUArAqTUvq05U+VoxtN7QEqR9bgdsRSByowVax | ||
/01r5CdrMC/xDs4OWz3sv8Kyw0hmd9nnCvMoMUQgEZsjNcEPmN7K | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIICazCCAdSgAwIBAgIJAMBBDJhEZSUlMA0GCSqGSIb3DQEBBQUAMC4xLDAqBgNV | ||
BAMTI0lOU0VDVVJFIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDcw | ||
OTAxNTkxN1oXDTI2MDUxOTE2MzM1N1owLjEsMCoGA1UEAxMjSU5TRUNVUkUgVGVz | ||
dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ | ||
AoGBAMAfEr8RkcWZhIwj7zz2F+phGpASWiO6EPUNsltXvksPo06DGJJJqWWJ/zUm | ||
/1m9Wjd0yx1dinT+C1jpViWTvJZ0KaSs29PW1EFuwZ8tOlm4TdWti6mGp9QZ5KVU | ||
24QXAAbrvXrEVBUfCmhd1gxrqvXH9gMbtndXtDnmbba6u2ehAgMBAAGjgZAwgY0w | ||
HQYDVR0OBBYEFJYXkYdQ2afmGvLRN9YGOqrGK/MLMF4GA1UdIwRXMFWAFJYXkYdQ | ||
2afmGvLRN9YGOqrGK/MLoTKkMDAuMSwwKgYDVQQDEyNJTlNFQ1VSRSBUZXN0IENl | ||
cnRpZmljYXRlIEF1dGhvcml0eYIJAMBBDJhEZSUlMAwGA1UdEwQFMAMBAf8wDQYJ | ||
KoZIhvcNAQEFBQADgYEAgN+TxBq4sYMnJZ3WHZ/RLcnpIbZdElUuM3lBbwKOmL5E | ||
KZ7uh5ZzyihNMnuw61MqvSMjwZfipyD0xNhX7e4dF47Q1oOUaMSxTS92PgQ22otY | ||
IMVtP7r8h8op7oKsiaSu4Y984abXirhMdVa1nUvyliBSYs94YIyZtwujhQJKN5Y= | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
MIICXgIBAAKBgQDAHxK/EZHFmYSMI+889hfqYRqQElojuhD1DbJbV75LD6NOgxiS | ||
Sallif81Jv9ZvVo3dMsdXYp0/gtY6VYlk7yWdCmkrNvT1tRBbsGfLTpZuE3VrYup | ||
hqfUGeSlVNuEFwAG6716xFQVHwpoXdYMa6r1x/YDG7Z3V7Q55m22urtnoQIDAQAB | ||
AoGAMJMqsDiG/Mj15GDpiiZGobHvf2HEfKf8xZiy8blbmarYhW9L9SC+vbeIWS4E | ||
/fGML91NxZzy9uWMhOxqJZIW6hsPbaZaxWcI/Ar78YcwskKRZC8vZd2bZ+jbwp6Y | ||
rI0/FVla42wcFXr6dbdnLKOeYBurB/F/839jeErjoWJ5F2kCQQDsmOl9A+ni+OYI | ||
We8/Vc/BASVnpKbvYYUi4BlzDjhcj5cn44pIuGRS/VDfmiQTGPf/gMOd6GM2jDUm | ||
kvFUZY5fAkEAz+BwsTZAwF9vPOBu9iuVsCzJ+OhyNtl1PrWDqEdMkFRHN++eXkL0 | ||
U4uNMLma3pCDLJ2bv49mTPzDu2AY03bJ/wJBALMSzW5MvwKGhnz9rOJQDa20M15t | ||
tdfrBLyvxzNZKPmNyMdtJiYCQhS6HDMRVIqL1HCzQdvLnwQTPMtUXooVT5sCQQDF | ||
BpFJJYbRzqJ8LKx/HmhOBuWXyZkXa5y4xwn2YT2sPnUSC0crSIKS/N3hpMmo0YfC | ||
rc+FDMGFjr1lx3tAUoK5AkEAiEbs3Kn1donT7bT5+WeTGSIIBnWN2s93Gq7AXpV3 | ||
K96lVDUnXa4qGwGdhmvlhXpwhYrzMNHkzaU/AcSOi3Cqww== | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIICGzCCAYSgAwIBAgIJALEY3/cqVrhXMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV | ||
BAMTCWxvY2FsaG9zdDAeFw0xMDA3MDkwMTU5MTdaFw0yNjA1MTkxNjMzNTdaMBQx | ||
EjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA | ||
oxTekB4FnMphxgXx4Mg+9v2pgXyh0f1krbcgafVP0P07F3Tb4iW2QwnSw5amSen6 | ||
RPNsA/R1qaYw0TG39gW4Wo3gx6dMynzsUVABdIrRaG2M1xsWX2C/iJOFZ50VVKre | ||
pmzxz5lMKusL8D9JwYAfuDgLnsN6ByLtIJ1/i/3ubucCAwEAAaN1MHMwHQYDVR0O | ||
BBYEFMXuuqokuPcMMS7OFu0jeoGKoJsDMEQGA1UdIwQ9MDuAFMXuuqokuPcMMS7O | ||
Fu0jeoGKoJsDoRikFjAUMRIwEAYDVQQDEwlsb2NhbGhvc3SCCQCxGN/3Kla4VzAM | ||
BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAKC8iJBjfAe78/QzKmMk6QJN | ||
kdLolcGGdINaCyGJRG67givjgkLj9N0JDJImeXWebyykrb/RKSNh7jAcBah+qnvS | ||
SkuXG5E2qKvG66rN/4sjhP68pvD10psvKY/pYmZTPu1VHLZXWwNHtKy/F/ktj/7P | ||
HyuNWpYma8yzHT8RMizZ | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAuMSwwKgYDVQQDEyNJTlNF | ||
Q1VSRSBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMDA3MDkwMTU5MTda | ||
Fw0xMDA4MDgwMTU5MTdaMBQxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG | ||
9w0BAQEFAAOBjQAwgYkCgYEAoxTekB4FnMphxgXx4Mg+9v2pgXyh0f1krbcgafVP | ||
0P07F3Tb4iW2QwnSw5amSen6RPNsA/R1qaYw0TG39gW4Wo3gx6dMynzsUVABdIrR | ||
aG2M1xsWX2C/iJOFZ50VVKrepmzxz5lMKusL8D9JwYAfuDgLnsN6ByLtIJ1/i/3u | ||
bucCAwEAAaNQME4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUxe66qiS49wwxLs4W | ||
7SN6gYqgmwMwHwYDVR0jBBgwFoAUlheRh1DZp+Ya8tE31gY6qsYr8wswDQYJKoZI | ||
hvcNAQEFBQADgYEAPRrgDgJG0YSDNUl57cghBqHvlb4QOZDGgW1XLiG2GYLl1o5Q | ||
jbHij7BZBdk4CBwr1vzExL6Ef7ktvhEEvgXEJQeiOU9Y+v/w3EG914dpJp39Epv6 | ||
vBvO9yAyAaozk7JvRGlB8nbb36pYuFnv+KsRNn/KFjauCXm+gknQRSP9vpE= | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
MIICXQIBAAKBgQCjFN6QHgWcymHGBfHgyD72/amBfKHR/WSttyBp9U/Q/TsXdNvi | ||
JbZDCdLDlqZJ6fpE82wD9HWppjDRMbf2BbhajeDHp0zKfOxRUAF0itFobYzXGxZf | ||
YL+Ik4VnnRVUqt6mbPHPmUwq6wvwP0nBgB+4OAuew3oHIu0gnX+L/e5u5wIDAQAB | ||
AoGBAJpAsie1De/5CbRJiTjpj40F79/3qAQ83o7lqTYv/7gY3lzYfucQbq5IS2AP | ||
TeiZ9MxlRuUSxHycIo6srWl6jZ0u1M4vfRvmQf2aXZbN4MPcY+XnpUCYGKgKBVLC | ||
tXoD9iHgCpvexbxjJgLIeeWotUoY3xAo8YnX2Luf+Vtah6dRAkEA03hLG+w8lov2 | ||
J3AfHQgKjKfRrMU5eC4P9I4LN+nLyHd7i6T+JP5V5NadRkN+xj0zHfo8PxjaPmDv | ||
QQqkhUlV3wJBAMVsGqa6NbtnCvHPc/M0XanBRuGejz2mDJqqaXMCBw8tY318XEMs | ||
gRdlDVWrNg7AcSEuzh48OA7c6lazKLa5N/kCQHhA69VRHZMuvCfpJohHzlf2BtIM | ||
xYWGDCSxscd1+CBjcaoThUJcL1QWhxExyKHKo4rkheYLp+/ZB7Ug7DWvYlkCQQCZ | ||
SO+Ehs5TfJVF3UJ1EjKrLHNhmOA1CKl+qVQIxQlAIoi+FQH58iMlTAPHgZEOcSMl | ||
lZbaaP1JpQOaX677+OHZAkA8vVYbYC+7t0SUqoY0X8z11Iobttpqir9trNq1CK8A | ||
/3To+/BFK2A6Sj7R5u90Vi523FpWq1a74oNAsnB3x7TU | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[ca] | ||
basicConstraints=critical,CA:true | ||
subjectKeyIdentifier=hash | ||
authorityKeyIdentifier=keyid:always,issuer:always | ||
|
||
[cert] | ||
basicConstraints=critical,CA:false | ||
subjectKeyIdentifier=hash | ||
authorityKeyIdentifier=keyid,issuer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) | ||
|
||
describe HTTParty::Request do | ||
context "SSL certificate verification" do | ||
before do | ||
FakeWeb.allow_net_connect = true # enable network connections just for this test | ||
end | ||
|
||
after do | ||
FakeWeb.allow_net_connect = false # Restore allow_net_connect value for testing | ||
end | ||
|
||
it "should work with when no trusted CA list is specified" do | ||
ssl_verify_test(nil, nil, "selfsigned.crt").should == {'success' => true} | ||
end | ||
|
||
it "should work with when no trusted CA list is specified, even with a bogus hostname" do | ||
ssl_verify_test(nil, nil, "bogushost.crt").should == {'success' => true} | ||
end | ||
|
||
it "should work when using ssl_ca_file with a self-signed CA" do | ||
ssl_verify_test(:ssl_ca_file, "selfsigned.crt", "selfsigned.crt").should == {'success' => true} | ||
end | ||
|
||
it "should work when using ssl_ca_file with a certificate authority" do | ||
ssl_verify_test(:ssl_ca_file, "ca.crt", "server.crt").should == {'success' => true} | ||
end | ||
it "should work when using ssl_ca_path with a certificate authority" do | ||
ssl_verify_test(:ssl_ca_path, ".", "server.crt").should == {'success' => true} | ||
end | ||
|
||
it "should fail when using ssl_ca_file and the server uses an unrecognized certificate authority" do | ||
lambda do | ||
ssl_verify_test(:ssl_ca_file, "ca.crt", "selfsigned.crt") | ||
end.should raise_error(OpenSSL::SSL::SSLError) | ||
end | ||
it "should fail when using ssl_ca_path and the server uses an unrecognized certificate authority" do | ||
lambda do | ||
ssl_verify_test(:ssl_ca_path, ".", "selfsigned.crt") | ||
end.should raise_error(OpenSSL::SSL::SSLError) | ||
end | ||
|
||
it "should fail when using ssl_ca_file and the server uses a bogus hostname" do | ||
lambda do | ||
ssl_verify_test(:ssl_ca_file, "ca.crt", "bogushost.crt") | ||
end.should raise_error(OpenSSL::SSL::SSLError) | ||
end | ||
it "should fail when using ssl_ca_path and the server uses a bogus hostname" do | ||
lambda do | ||
ssl_verify_test(:ssl_ca_path, ".", "bogushost.crt") | ||
end.should raise_error(OpenSSL::SSL::SSLError) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module HTTParty | ||
module SSLTestHelper | ||
def ssl_verify_test(mode, ca_basename, server_cert_filename) | ||
test_server = nil | ||
begin | ||
# Start an HTTPS server | ||
test_server = SSLTestServer.new( | ||
:rsa_key => File.read(File.expand_path("../../fixtures/ssl/generated/server.key", __FILE__)), | ||
:cert => File.read(File.expand_path("../../fixtures/ssl/generated/#{server_cert_filename}", __FILE__))) | ||
test_server.start | ||
|
||
# Build a request | ||
if mode | ||
ca_path = File.expand_path("../../fixtures/ssl/generated/#{ca_basename}", __FILE__) | ||
raise ArgumentError.new("#{ca_path} does not exist") unless File.exist?(ca_path) | ||
return HTTParty.get("https://localhost:#{test_server.port}/", :format => :json, :timeout=>30, mode => ca_path) | ||
else | ||
return HTTParty.get("https://localhost:#{test_server.port}/", :format => :json, :timeout=>30) | ||
end | ||
ensure | ||
test_server.stop if test_server | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
require 'openssl' | ||
require 'socket' | ||
require 'thread' | ||
|
||
# NOTE: This code is garbage. It probably has deadlocks, it might leak | ||
# threads, and otherwise cause problems in a real system. It's really only | ||
# intended for testing HTTParty. | ||
class SSLTestServer | ||
attr_accessor :ctx # SSLContext object | ||
attr_reader :port | ||
|
||
def initialize(options={}) | ||
@ctx = OpenSSL::SSL::SSLContext.new | ||
@ctx.cert = OpenSSL::X509::Certificate.new(options[:cert]) | ||
@ctx.key = OpenSSL::PKey::RSA.new(options[:rsa_key]) | ||
@ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE # Don't verify client certificate | ||
@port = options[:port] || 0 | ||
@thread = nil | ||
@stopping_mutex = Mutex.new | ||
@stopping = false | ||
end | ||
|
||
def start | ||
@raw_server = TCPServer.new(@port) | ||
if @port == 0 | ||
@port = Socket::getnameinfo(@raw_server.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)[1].to_i | ||
end | ||
@ssl_server = OpenSSL::SSL::SSLServer.new(@raw_server, @ctx) | ||
@stopping_mutex.synchronize{ | ||
return if @stopping | ||
@thread = Thread.new{ thread_main } | ||
} | ||
nil | ||
end | ||
|
||
def stop | ||
@stopping_mutex.synchronize{ | ||
return if @stopping | ||
@stopping = true | ||
} | ||
@thread.join | ||
end | ||
|
||
private | ||
|
||
def thread_main | ||
until @stopping_mutex.synchronize{ @stopping } | ||
(rr,ww,ee) = select([@ssl_server.to_io], nil, nil, 0.1) | ||
next unless rr && rr.include?(@ssl_server.to_io) | ||
socket = @ssl_server.accept | ||
Thread.new{ | ||
header = [] | ||
until (line = socket.readline).rstrip.empty? | ||
header << line | ||
end | ||
|
||
socket.write <<'EOF'.gsub(/\r\n/n, "\n").gsub(/\n/n, "\r\n") | ||
HTTP/1.1 200 OK | ||
Connection: close | ||
Content-Type: application/json; charset=UTF-8 | ||
{"success":true} | ||
EOF | ||
socket.close | ||
} | ||
end | ||
@ssl_server.close | ||
end | ||
end |