8000 SSL Peer Verification and other SSL improvements by burke · Pull Request #334 · eventmachine/eventmachine · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

SSL Peer Verification and other SSL improvements #334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
377b53a
added private key password, and server certificate verification
Jun 1, 2010
46e254f
add 'tags' to .gitignore
May 22, 2012
9a75cce
Change SSL verification wrapper to pass OpenSSL's result to ruby.
May 22, 2012
ea3f730
Merged #84. This improves support for providing credentials to OpenSSL
May 22, 2012
980c32b
Remove changelog-style comments. Git history shows the same.
May 22, 2012
c93ddbb
Refactor repeated code in ssl.cpp
May 22, 2012
31c30d8
Refactor logic in SslContext_t constructor.
May 22, 2012
26219e7
Remove commented code.
May 22, 2012
e91c6b7
Refactor test_ssl_verify a bit.
May 22, 2012
3bf5015
SSl-ified SendOutboundData now properly returns data length.
May 23, 2012
804758e
Added support to the ssl_verify_wrapper for printing debug info.
May 23, 2012
fe1efc4
Added `hostname` parameter to `set_tls_parms` to use for CN verification
< 8000 span class="description"> May 24, 2012
5cdf745
Raise an error if ca_file is given but non-existent.
May 24, 2012
3b4a93a
ssl_verify_wrapper now checks CN against expected hostname
May 24, 2012
eee4b2d
Updates docs in EM::Connection to reflect new SSL details.
May 24, 2012
24daeec
Improve ruby start_tls method:
May 24, 2012
a01dbc2
Improved SSL verification tests and added new certificates
May 24, 2012
26d5cce
Support SNI for client connections.
May 28, 2012
99df767
Adds real domain verification as per RFC 6125.
May 28, 2012
e65d940
Properly ignore case in hostname comparisons.
May 28, 2012
ba6058c
Properly handle a wildcard in the last component of a hostname.
May 28, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ Gemfile.lock
.yardoc/*
doc/*

tags
3,331 changes: 3,331 additions & 0 deletions cacert.pem

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions ext/cmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,12 +432,12 @@ extern "C" void evma_start_tls (const unsigned long binding)
evma_set_tls_parms
******************/

extern "C" void evma_set_tls_parms (const unsigned long binding, const char *privatekey_filename, const char *certchain_filename, int verify_peer)
extern "C" void evma_set_tls_parms (const unsigned long binding, const char *ca_filename, const char *privatekey_filename, const char *privatekey_pwd, const char *certchain_filename, const char *hostname, int verify_peer)
{
ensure_eventmachine("evma_set_tls_parms");
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
if (ed)
ed->SetTlsParms (privatekey_filename, certchain_filename, (verify_peer == 1 ? true : false));
ed->SetTlsParms (ca_filename, privatekey_filename, privatekey_pwd, certchain_filename, hostname, (verify_peer == 1 ? true : false));
}

/******************
Expand Down
22 changes: 15 additions & 7 deletions ext/ed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,7 @@ int ConnectionDescriptor::SendOutboundData (const char *data, int length)
else
_DispatchCiphertext();
}
// TODO: What's the correct return value?
return 1; // That's a wild guess, almost certainly wrong.
return length;
}
else
#endif
Expand Down Expand Up @@ -1132,7 +1131,7 @@ void ConnectionDescriptor::StartTls()
if (SslBox)
throw std::runtime_error ("SSL/TLS already running on connection");

SslBox = new SslBox_t (bIsServer, PrivateKeyFilename, CertChainFilename, bSslVerifyPeer, GetBinding());
SslBox = new SslBox_t (bIsServer, CAFilename, PrivateKeyFilename, PrivateKeyPwd, CertChainFilename, Hostname, bSslVerifyPeer, GetBinding());
_DispatchCiphertext();
#endif

Expand All @@ -1146,15 +1145,22 @@ void ConnectionDescriptor::StartTls()
ConnectionDescriptor::SetTlsParms
*********************************/

void ConnectionDescriptor::SetTlsParms (const char *privkey_filename, const char *certchain_filename, bool verify_peer)
void ConnectionDescriptor::SetTlsParms (const char *ca_filename, const char *privkey_filename, const char *privkey_pwd, const char *certchain_filename, const char *hostname, bool verify_peer)
{
#ifdef WITH_SSL
if (SslBox)
throw std::runtime_error ("call SetTlsParms before calling StartTls");
if (privkey_filename && *privkey_filename)
if (privkey_filename && *privkey_filename) {
PrivateKeyFilename = privkey_filename;
if (privkey_pwd && *privkey_pwd)
PrivateKeyPwd = privkey_pwd;
}
if (ca_filename && *ca_filename)
CAFilename = ca_filename;
if (certchain_filename && *certchain_filename)
CertChainFilename = certchain_filename;
if (hostname && *hostname)
Hostname = hostname;
bSslVerifyPeer = verify_peer;
#endif

Expand Down Expand Up @@ -1183,12 +1189,14 @@ ConnectionDescriptor::VerifySslPeer
***********************************/

#ifdef WITH_SSL
bool ConnectionDescriptor::VerifySslPeer(const char *cert)
bool ConnectionDescriptor::VerifySslPeer(const char *cert, int preverify_ok)
{
bSslPeerAccepted = false;

int message = (preverify_ok == 1 ? EM_SSL_VERIFY_SUCCESS : EM_SSL_VERIFY_FAILURE);

if (EventCallback)
(*EventCallback)(GetBinding(), EM_SSL_VERIFY, cert, strlen(cert));
(*EventCallback)(GetBinding(), message, cert, strlen(cert));

return bSslPeerAccepted;
}
Expand Down
9 changes: 6 additions & 3 deletions ext/ed.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class EventableDescriptor: public Bindable_t
virtual bool GetSubprocessPid (pid_t*) {return false;}

virtual void StartTls() {}
virtual void SetTlsParms (const char *privkey_filename, const char *certchain_filename, bool verify_peer) {}
virtual void SetTlsParms (const char *ca_filename, const char *privkey_filename, const char *privkey_file_pwd, const char *certchain_filename, const char *hostname, bool verify_peer) {}

#ifdef WITH_SSL
virtual X509 *GetPeerCert() {return NULL;}
Expand Down Expand Up @@ -193,11 +193,11 @@ class ConnectionDescriptor: public EventableDescriptor
virtual int GetOutboundDataSize() {return OutboundDataSize;}

virtual void StartTls();
virtual void SetTlsParms (const char *privkey_filename, const char *certchain_filename, bool verify_peer);
virtual void SetTlsParms (const char *ca_filename, const char *privkey_filename, const char *privkey_pwd, const char *certchain_filename, const char *hostname, bool verify_peer);

#ifdef WITH_SSL
virtual X509 *GetPeerCert();
virtual bool VerifySslPeer(const char*);
virtual bool VerifySslPeer(const char*, int);
virtual void AcceptSslPeer();
#endif

Expand Down Expand Up @@ -236,7 +236,10 @@ class ConnectionDescriptor: public EventableDescriptor
#ifdef WITH_SSL
SslBox_t *SslBox;
std::string CertChainFilename;
std::string CAFilename;
std::string PrivateKeyFilename;
std::string PrivateKeyPwd;
std::string Hostname;
bool bHandshakeSignaled;
bool bSslVerifyPeer;
bool bSslPeerAccepted;
Expand Down
8 changes: 5 additions & 3 deletions ext/eventmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ extern "C" {
EM_CONNECTION_NOTIFY_READABLE = 106,
EM_CONNECTION_NOTIFY_WRITABLE = 107,
EM_SSL_HANDSHAKE_COMPLETED = 108,
EM_SSL_VERIFY = 109,
// EM_SSL_VERIFY = 109, -- deprecated for 112 & 113. reuse?
EM_PROXY_TARGET_UNBOUND = 110,
EM_PROXY_COMPLETED = 111
EM_PROXY_COMPLETED = 111,
EM_SSL_VERIFY_SUCCESS = 112,
EM_SSL_VERIFY_FAILURE = 113

};

Expand Down Expand Up @@ -66,7 +68,7 @@ extern "C" {
const unsigned long evma_create_unix_domain_server (const char *filename);
const unsigned long evma_open_datagram_socket (const char *server, int port);
const unsigned long evma_open_keyboard();
void evma_set_tls_parms (const unsigned long binding, const char *privatekey_filename, const char *certchain_filenane, int verify_peer);
void evma_set_tls_parms (const unsigned long binding, const char *ca_filename, const char *privatekey_filename, const char *privatekey_pwd, const char *certchain_filenane, const char *hostname, int verify_peer);
void evma_start_tls (const unsigned long binding);

#ifdef WITH_SSL
Expand Down
1 change: 1 addition & 0 deletions ext/project.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ using namespace std;
#ifdef WITH_SSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#endif

#ifdef HAVE_EPOLL
Expand Down
26 changes: 21 additions & 5 deletions ext/rubymain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,26 @@ static inline void event_callback (struct em_event* e)
rb_funcall (conn, Intern_ssl_handshake_completed, 0);
return;
}
case EM_SSL_VERIFY:
case EM_SSL_VERIFY_SUCCESS:
{
VALUE conn = ensure_conn(signature);
VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num));
VALUE should_accept;
if (rb_obj_method_arity(conn, Intern_ssl_verify_peer) == 1)
should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num));
else
should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 2, rb_str_new(data_str, data_num), Qtrue);
if (RTEST(should_accept))
evma_accept_ssl_peer (signature);
return;
}
case EM_SSL_VERIFY_FAILURE:
{
VALUE conn = ensure_conn(signature);
VALUE should_accept;
if (rb_obj_method_arity(conn, Intern_ssl_verify_peer) == 1)
should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num));
else
should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 2, rb_str_new(data_str, data_num), Qfalse);
if (RTEST(should_accept))
evma_accept_ssl_peer (signature);
return;
Expand Down Expand Up @@ -300,14 +316,14 @@ static VALUE t_start_tls (VALUE self, VALUE signature)
t_set_tls_parms
***************/

static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer)
static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE cafile, VALUE privkeyfile, VALUE privkeypwd, VALUE certchainfile, VALUE hostname, VALUE verify_peer)
{
/* set_tls_parms takes a series of positional arguments for specifying such things
* as private keys and certificate chains.
* It's expected that the parameter list will grow as we add more supported features.
* ALL of these parameters are optional, and can be specified as empty or NULL strings.
*/
evma_set_tls_parms (NUM2ULONG (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
evma_set_tls_parms (NUM2ULONG (signature), StringValuePtr (cafile), StringValuePtr (privkeyfile), StringValuePtr (privkeypwd), StringValuePtr (certchainfile), StringValuePtr (hostname), (verify_peer == Qtrue ? 1 : 0));
return Qnil;
}

Expand Down Expand Up @@ -1204,7 +1220,7 @@ extern "C" void Init_rubyeventmachine()
rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 4);
rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 7);
rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
rb_define_module_function (EmModule, "get_peer_cert", (VALUE(*)(...))t_get_peer_cert, 1);
rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
Expand Down
Loading
0