Skip to content
This repository

Fix for issues #275 (and duplicate issues #195) : add SSL_VERIFY_FAIL_IF_NO_PEER_CERT option #299

Closed
wants to merge 3 commits into from

2 participants

caiquanqing Iñaki Baz Castillo
caiquanqing

Here is fix for isses #275 ( and duplicate issues #195 ).

SSL_VERIFY_FAIL_IF_NO_PEER_CERT option is explained here.

Iñaki Baz Castillo

Nice. Hope this is accepted in EM master.

caiquanqing caiquanqing closed this April 25, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
4  ext/ed.cpp
@@ -1188,12 +1188,12 @@ ConnectionDescriptor::VerifySslPeer
1188 1188
 ***********************************/
1189 1189
 
1190 1190
 #ifdef WITH_SSL
1191  
-bool ConnectionDescriptor::VerifySslPeer(const char *cert)
  1191
+bool ConnectionDescriptor::VerifySslPeer(struct ssl_verify_callback *ssl_verify_callback_data)
1192 1192
 {
1193 1193
 	bSslPeerAccepted = false;
1194 1194
 
1195 1195
 	if (EventCallback)
1196  
-		(*EventCallback)(GetBinding(), EM_SSL_VERIFY, cert, strlen(cert));
  1196
+		(*EventCallback)(GetBinding(), EM_SSL_VERIFY, (const char *)ssl_verify_callback_data, sizeof(*ssl_verify_callback_data));
1197 1197
 
1198 1198
 	return bSslPeerAccepted;
1199 1199
 }
2  ext/ed.h
@@ -197,7 +197,7 @@ class ConnectionDescriptor: public EventableDescriptor
197 197
 
198 198
 		#ifdef WITH_SSL
199 199
 		virtual X509 *GetPeerCert();
200  
-		virtual bool VerifySslPeer(const char*);
  200
+		virtual bool VerifySslPeer(struct ssl_verify_callback *);
201 201
 		virtual void AcceptSslPeer();
202 202
 		#endif
203 203
 
3  ext/rubymain.cpp
@@ -148,8 +148,9 @@ static inline void event_callback (struct em_event* e)
148 148
 		}
149 149
 		case EM_SSL_VERIFY:
150 150
 		{
  151
+			struct ssl_verify_callback *ssl_verify_callback_data = (struct ssl_verify_callback *) data_str;
151 152
 			VALUE conn = ensure_conn(signature);
152  
-			VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num));
  153
+			VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 5, (ssl_verify_callback_data->preverify_ok==1)?Qtrue:Qfalse, rb_str_new2(ssl_verify_callback_data->cert), INT2NUM(ssl_verify_callback_data->depth), INT2NUM(ssl_verify_callback_data->err), rb_str_new2(ssl_verify_callback_data->error_string));
153 154
 			if (RTEST(should_accept))
154 155
 				evma_accept_ssl_peer (signature);
155 156
 			return;
14  ext/ssl.cpp
@@ -186,6 +186,7 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str
186 186
 			if (e <= 0) ERR_print_errors_fp(stderr);
187 187
 			assert (e > 0);
188 188
 		}
  189
+
189 190
 		if (certchainfile.length() > 0) {
190 191
 			e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
191 192
 			if (e <= 0) ERR_print_errors_fp(stderr);
@@ -245,7 +246,7 @@ SslBox_t::SslBox_t (bool is_server, const string &privkeyfile, const string &cer
245 246
 	SSL_set_ex_data(pSSL, 0, (void*) binding);
246 247
 
247 248
 	if (bVerifyPeer)
248  
-		SSL_set_verify(pSSL, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, ssl_verify_wrapper);
  249
+		SSL_set_verify(pSSL, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, ssl_verify_wrapper);
249 250
 
250 251
 	if (!bIsServer)
251 252
 		SSL_connect (pSSL);
@@ -447,8 +448,11 @@ extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx)
447 448
 	BUF_MEM *buf;
448 449
 	BIO *out;
449 450
 	int result;
  451
+	int err;
  452
+	struct ssl_verify_callback ssl_verify_callback_data;
450 453
 
451 454
 	cert = X509_STORE_CTX_get_current_cert(ctx);
  455
+	err = X509_STORE_CTX_get_error(ctx);
452 456
 	ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
453 457
 	binding = (unsigned long) SSL_get_ex_data(ssl, 0);
454 458
 
@@ -456,9 +460,15 @@ extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx)
456 460
 	PEM_write_bio_X509(out, cert);
457 461
 	BIO_write(out, "\0", 1);
458 462
 	BIO_get_mem_ptr(out, &buf);
  463
+	
  464
+	ssl_verify_callback_data.preverify_ok = preverify_ok;
  465
+	ssl_verify_callback_data.depth = X509_STORE_CTX_get_error_depth(ctx);
  466
+	ssl_verify_callback_data.err = err;
  467
+	ssl_verify_callback_data.cert = buf->data;
  468
+	ssl_verify_callback_data.error_string = X509_verify_cert_error_string(err);
459 469
 
460 470
 	ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject(binding));
461  
-	result = (cd->VerifySslPeer(buf->data) == true ? 1 : 0);
  471
+	result = (cd->VerifySslPeer(&ssl_verify_callback_data) == true ? 1 : 0);
462 472
 	BIO_free(out);
463 473
 
464 474
 	return result;
8  ext/ssl.h
@@ -87,6 +87,14 @@ class SslBox_t
87 87
 
88 88
 extern "C" int ssl_verify_wrapper(int, X509_STORE_CTX*);
89 89
 
  90
+struct ssl_verify_callback {
  91
+	int preverify_ok;
  92
+	int depth;
  93
+	int err;
  94
+	const char *cert;
  95
+	const char *error_string;
  96
+};
  97
+
90 98
 #endif // WITH_SSL
91 99
 
92 100
 
7  lib/em/connection.rb
@@ -142,7 +142,7 @@ def ssl_handshake_completed
142 142
     #       start_tls(:verify_peer => true)
143 143
     #     end
144 144
     #
145  
-    #     def ssl_verify_peer(cert)
  145
+    #     def ssl_verify_peer(preverify_ok, cert, depth, err, error_string)
146 146
     #       true
147 147
     #     end
148 148
     #
@@ -159,7 +159,7 @@ def ssl_handshake_completed
159 159
     #       start_tls(:verify_peer => true)
160 160
     #     end
161 161
     #
162  
-    #     def ssl_verify_peer(cert)
  162
+    #     def ssl_verify_peer(preverify_ok, cert, depth, err, error_string)
163 163
     #       # Do not accept the peer. This should now cause the connection to shut down
164 164
     #       # without the SSL handshake being completed.
165 165
     #       false
@@ -171,7 +171,8 @@ def ssl_handshake_completed
171 171
     #   end
172 172
     #
173 173
     # @see #start_tls
174  
-    def ssl_verify_peer(cert)
  174
+    def ssl_verify_peer(preverify_ok, cert, depth, err, error_string)
  175
+	  return preverify_ok
175 176
     end
176 177
 
177 178
     # called by the framework whenever a connection (either a server or client connection) is closed.
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.