Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: c/sslnetwork.c

Issue 2842333002: Updated netty-tcnative to version 2.0.0.Final (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « c/sslinfo.c ('k') | c/sslutils.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /** SSL network wrapper
18 *
19 * @author Mladen Turk
20 * @version $Id: sslnetwork.c 1658646 2015-02-10 09:00:11Z rjung $
21 */
22
23 #include "tcn.h"
24 #include "apr_thread_mutex.h"
25 #include "apr_poll.h"
26
27
28 #ifdef HAVE_OPENSSL
29 #include "ssl_private.h"
30
31 #ifdef TCN_DO_STATISTICS
32 #include "apr_atomic.h"
33
34 static volatile apr_uint32_t ssl_created = 0;
35 static volatile apr_uint32_t ssl_closed = 0;
36 static volatile apr_uint32_t ssl_cleared = 0;
37 static volatile apr_uint32_t ssl_accepted = 0;
38
39 void ssl_network_dump_statistics()
40 {
41 fprintf(stderr, "SSL Network Statistics ..\n");
42 fprintf(stderr, "Sockets created : %d\n", ssl_created);
43 fprintf(stderr, "Sockets accepted : %d\n", ssl_accepted);
44 fprintf(stderr, "Sockets closed : %d\n", ssl_closed);
45 fprintf(stderr, "Sockets cleared : %d\n", ssl_cleared);
46 }
47
48 #endif
49
50 static int ssl_smart_shutdown(SSL *ssl, int shutdown_type)
51 {
52 int i;
53 int rc = 0;
54
55 switch (shutdown_type) {
56 case SSL_SHUTDOWN_TYPE_UNCLEAN:
57 /* perform no close notify handshake at all
58 * (violates the SSL/TLS standard!)
59 */
60 shutdown_type = SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN;
61 break;
62 case SSL_SHUTDOWN_TYPE_ACCURATE:
63 /* send close notify and wait for clients close notify
64 * (standard compliant, but usually causes connection hangs)
65 */
66 shutdown_type = 0;
67 break;
68 default:
69 /*
70 * case SSL_SHUTDOWN_TYPE_UNSET:
71 * case SSL_SHUTDOWN_TYPE_STANDARD:
72 * send close notify, but don't wait for clients close notify
73 * (standard compliant and safe, so it's the DEFAULT!)
74 */
75 shutdown_type = SSL_RECEIVED_SHUTDOWN;
76 break;
77 }
78
79 SSL_set_shutdown(ssl, shutdown_type);
80 /*
81 * Repeat the calls, because SSL_shutdown internally dispatches through a
82 * little state machine. Usually only one or two interation should be
83 * needed, so we restrict the total number of restrictions in order to
84 * avoid process hangs in case the client played bad with the socket
85 * connection and OpenSSL cannot recognize it.
86 * max 2x pending + 2x data = 4
87 */
88 for (i = 0; i < 4; i++) {
89 if ((rc = SSL_shutdown(ssl)))
90 break;
91 }
92 return rc;
93 }
94
95 static apr_status_t ssl_cleanup(void *data)
96 {
97 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)data;
98
99 if (con) {
100 /* Pollset was already destroyed by
101 * the pool cleanup/destroy.
102 */
103 con->pollset = NULL;
104 if (con->ssl) {
105 SSL *ssl = con->ssl;
106 con->ssl = NULL;
107 ssl_smart_shutdown(ssl, con->shutdown_type);
108 SSL_free(ssl);
109 }
110 if (con->peer) {
111 X509_free(con->peer);
112 con->peer = NULL;
113 }
114 }
115
116 #ifdef TCN_DO_STATISTICS
117 apr_atomic_inc32(&ssl_cleared);
118 #endif
119 return APR_SUCCESS;
120 }
121
122 static tcn_ssl_conn_t *ssl_create(JNIEnv *env, tcn_ssl_ctxt_t *ctx, apr_pool_t * pool)
123 {
124 tcn_ssl_conn_t *con;
125 SSL *ssl;
126
127 if ((con = apr_pcalloc(pool, sizeof(tcn_ssl_conn_t))) == NULL) {
128 tcn_ThrowAPRException(env, apr_get_os_error());
129 return NULL;
130 }
131 if ((ssl = SSL_new(ctx->ctx)) == NULL) {
132 char err[256];
133 ERR_error_string(ERR_get_error(), err);
134 tcn_Throw(env, "SSL_new failed (%s)", err);
135 con = NULL;
136 return NULL;
137 }
138 SSL_clear(ssl);
139 con->pool = pool;
140 con->ctx = ctx;
141 con->ssl = ssl;
142 con->shutdown_type = ctx->shutdown_type;
143 apr_pollset_create(&(con->pollset), 1, pool, 0);
144
145 SSL_set_app_data(ssl, (void *)con);
146
147 // Store for later usage in SSL_callback_SSL_verify
148 SSL_set_app_data2(ssl, ctx);
149
150 if (ctx->mode) {
151 /*
152 * Configure callbacks for SSL connection
153 */
154 SSL_set_tmp_rsa_callback(ssl, SSL_callback_tmp_RSA);
155 SSL_set_tmp_dh_callback(ssl, SSL_callback_tmp_DH);
156 SSL_set_session_id_context(ssl, &(ctx->context_id[0]),
157 sizeof ctx->context_id);
158 }
159 SSL_set_verify_result(ssl, X509_V_OK);
160 SSL_rand_seed(ctx->rand_file);
161
162 #ifdef TCN_DO_STATISTICS
163 ssl_created++;
164 #endif
165 return con;
166 }
167
168 #ifdef WIN32
169 #define APR_INVALID_SOCKET INVALID_SOCKET
170 #else
171 #define APR_INVALID_SOCKET -1
172 #endif
173
174 static apr_status_t wait_for_io_or_timeout(tcn_ssl_conn_t *con,
175 int for_what,
176 apr_interval_time_t timeout)
177 {
178 apr_pollfd_t pfd;
179 int type;
180 apr_status_t status;
181 apr_os_sock_t sock;
182
183 if (!con->pollset)
184 return APR_ENOPOLL;
185 if (!con->sock)
186 return APR_ENOTSOCK;
187 if (con->reneg_state == RENEG_ABORT) {
188 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
189 return APR_ECONNABORTED;
190 }
191
192 /* Check if the socket was already closed
193 */
194 apr_os_sock_get(&sock, con->sock);
195 if (sock == APR_INVALID_SOCKET)
196 return APR_ENOTSOCK;
197
198 /* Figure out the the poll direction */
199 switch (for_what) {
200 case SSL_ERROR_WANT_WRITE:
201 case SSL_ERROR_WANT_CONNECT:
202 case SSL_ERROR_WANT_ACCEPT:
203 type = APR_POLLOUT;
204 break;
205 case SSL_ERROR_WANT_READ:
206 type = APR_POLLIN;
207 break;
208 default:
209 return APR_EINVAL;
210 break;
211 }
212 if (timeout <= 0) {
213 /* Waiting on zero or infinite timeouts is not allowed
214 */
215 return APR_EAGAIN;
216 }
217 pfd.desc_type = APR_POLL_SOCKET;
218 pfd.desc.s = con->sock;
219 pfd.reqevents = type;
220
221 /* Remove the object if it was in the pollset, then add in the new
222 * object with the correct reqevents value. Ignore the status result
223 * on the remove, because it might not be in there (yet).
224 */
225 apr_pollset_remove(con->pollset, &pfd);
226
227 /* ### check status code */
228 apr_pollset_add(con->pollset, &pfd);
229
230 do {
231 int numdesc;
232 const apr_pollfd_t *pdesc;
233
234 status = apr_pollset_poll(con->pollset, timeout, &numdesc, &pdesc);
235 if (numdesc == 1 && (pdesc[0].rtnevents & type) != 0)
236 return APR_SUCCESS;
237 } while (APR_STATUS_IS_EINTR(status));
238
239 return status;
240 }
241
242 static apr_status_t APR_THREAD_FUNC
243 ssl_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
244 {
245 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
246 return apr_socket_timeout_set(con->sock, t);
247 }
248
249 static apr_status_t APR_THREAD_FUNC
250 ssl_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
251 {
252 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
253 return apr_socket_timeout_get(con->sock, t);
254 }
255
256 static APR_INLINE apr_status_t APR_THREAD_FUNC
257 ssl_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
258 {
259 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
260 return apr_socket_opt_set(con->sock, opt, on);
261 }
262
263 static APR_INLINE apr_status_t APR_THREAD_FUNC
264 ssl_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on)
265 {
266 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
267 return apr_socket_opt_get(con->sock, opt, on);
268 }
269
270 static apr_status_t APR_THREAD_FUNC
271 ssl_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how)
272 {
273 apr_status_t rv = APR_SUCCESS;
274 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
275
276 if (con->ssl) {
277 SSL *ssl = con->ssl;
278 con->ssl = NULL;
279 if (how < 1)
280 how = con->shutdown_type;
281 rv = ssl_smart_shutdown(ssl, how);
282 /* TODO: Translate OpenSSL Error codes */
283 SSL_free(ssl);
284 }
285 return rv;
286 }
287
288 static apr_status_t APR_THREAD_FUNC
289 ssl_socket_close(apr_socket_t *sock)
290 {
291 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
292 apr_status_t rv = APR_SUCCESS;
293
294 #ifdef TCN_DO_STATISTICS
295 apr_atomic_inc32(&ssl_closed);
296 #endif
297 if (con->ssl) {
298 SSL *ssl = con->ssl;
299 con->ssl = NULL;
300 rv = ssl_smart_shutdown(ssl, con->shutdown_type);
301 SSL_free(ssl);
302 }
303 if (con->peer) {
304 X509_free(con->peer);
305 con->peer = NULL;
306 }
307 return rv;
308 }
309
310 TCN_IMPLEMENT_CALL(jint, SSLSocket, handshake)(TCN_STDARGS, jlong sock)
311 {
312 tcn_socket_t *ss = J2P(sock, tcn_socket_t *);
313 tcn_ssl_conn_t *con;
314 apr_interval_time_t timeout;
315 int s, i;
316 long vr;
317 apr_status_t rv;
318 X509 *peer;
319
320 UNREFERENCED_STDARGS;
321 TCN_ASSERT(sock != 0);
322 if (ss->net->type != TCN_SOCKET_SSL)
323 return APR_EINVAL;
324 con = (tcn_ssl_conn_t *)ss->opaque;
325
326 apr_socket_timeout_get(con->sock, &timeout);
327 while (!SSL_is_init_finished(con->ssl)) {
328 ERR_clear_error();
329 if ((s = SSL_do_handshake(con->ssl)) <= 0) {
330 if (!con->ssl)
331 return APR_ENOTSOCK;
332 rv = apr_get_netos_error();
333 i = SSL_get_error(con->ssl, s);
334 switch (i) {
335 case SSL_ERROR_NONE:
336 con->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
337 return APR_SUCCESS;
338 break;
339 case SSL_ERROR_WANT_READ:
340 case SSL_ERROR_WANT_WRITE:
341 if ((rv = wait_for_io_or_timeout(con, i, timeout)) != APR_SU CCESS) {
342 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
343 return rv;
344 }
345 break;
346 case SSL_ERROR_SYSCALL:
347 #if !defined(_WIN32)
348 if (APR_STATUS_IS_EINTR(rv)) {
349 /* Interrupted by signal */
350 continue;
351 }
352 #endif
353 /* Fall trough */
354 default:
355 /*
356 * Anything else is a fatal error
357 */
358 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
359 return SSL_TO_APR_ERROR(i);
360 break;
361 }
362 }
363 if (!con->ssl)
364 return APR_ENOTSOCK;
365
366 /*
367 * Check for failed client authentication
368 */
369 if ((vr = SSL_get_verify_result(con->ssl)) != X509_V_OK) {
370 if (SSL_VERIFY_ERROR_IS_OPTIONAL(vr) &&
371 con->ctx->verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA) {
372 /* TODO: Log optionalNoCA */
373 }
374 else {
375 /* TODO: Log SSL client authentication failed */
376 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
377 /* TODO: Figure out the correct return value */
378 return APR_EGENERAL;
379 }
380 }
381
382 /*
383 * Remember the peer certificate
384 */
385 if ((peer = SSL_get_peer_certificate(con->ssl)) != NULL) {
386 if (con->peer)
387 X509_free(con->peer);
388 con->peer = peer;
389 }
390 }
391 return APR_SUCCESS;
392 }
393
394 static apr_status_t APR_THREAD_FUNC
395 ssl_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
396 {
397 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
398 int s, i, rd = (int)(*len);
399 apr_status_t rv;
400 apr_interval_time_t timeout;
401
402 *len = 0;
403 if (con->reneg_state == RENEG_ABORT) {
404 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
405 return APR_ECONNABORTED;
406 }
407 apr_socket_timeout_get(con->sock, &timeout);
408 for (;;) {
409 ERR_clear_error();
410 if ((s = SSL_read(con->ssl, buf, rd)) <= 0) {
411 if (!con->ssl)
412 return APR_ENOTSOCK;
413 rv = apr_get_netos_error();
414 i = SSL_get_error(con->ssl, s);
415 /* Special case if the "close notify" alert send by peer */
416 if (s == 0 && (SSL_get_shutdown(con->ssl) & SSL_RECEIVED_SHUTDOWN)) {
417 con->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
418 return APR_EOF;
419 }
420 switch (i) {
421 case SSL_ERROR_WANT_READ:
422 case SSL_ERROR_WANT_WRITE:
423 if ((rv = wait_for_io_or_timeout(con, i, timeout)) != APR_SU CCESS) {
424 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
425 return rv;
426 }
427 break;
428 case SSL_ERROR_SYSCALL:
429 if (APR_STATUS_IS_EPIPE(rv) || APR_STATUS_IS_ECONNRESET(rv)) {
430 con->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
431 return APR_EOF;
432 }
433 #if !defined(_WIN32)
434 else if (APR_STATUS_IS_EINTR(rv)) {
435 /* Interrupted by signal
436 */
437 continue;
438 }
439 #endif
440 /* Fall trough */
441 case SSL_ERROR_ZERO_RETURN:
442 if (s == 0) {
443 con->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
444 return APR_EOF;
445 }
446 /* Fall trough */
447 default:
448 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
449 return APR_EGENERAL;
450 break;
451 }
452 }
453 else {
454 *len = s;
455 con->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
456 break;
457 }
458 }
459 return APR_SUCCESS;
460 }
461
462 static apr_status_t APR_THREAD_FUNC
463 ssl_socket_send(apr_socket_t *sock, const char *buf,
464 apr_size_t *len)
465 {
466 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
467 int s, i, wr = (int)(*len);
468 apr_status_t rv;
469 apr_interval_time_t timeout;
470
471 *len = 0;
472 if (con->reneg_state == RENEG_ABORT) {
473 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
474 return APR_ECONNABORTED;
475 }
476 if (!SSL_is_init_finished(con->ssl)) {
477 /* XXX: Is this a correct retval ? */
478 return APR_EINPROGRESS;
479 }
480 if (wr == 0) {
481 /* According to docs calling SSL_write() with num=0 bytes
482 * to be sent the behaviour is undefined.
483 */
484 return APR_EINVAL;
485 }
486 apr_socket_timeout_get(con->sock, &timeout);
487 for (;;) {
488 ERR_clear_error();
489 if ((s = SSL_write(con->ssl, buf, wr)) <= 0) {
490 if (!con->ssl)
491 return APR_ENOTSOCK;
492 rv = apr_get_netos_error();
493 i = SSL_get_error(con->ssl, s);
494 switch (i) {
495 case SSL_ERROR_WANT_READ:
496 case SSL_ERROR_WANT_WRITE:
497 if ((rv = wait_for_io_or_timeout(con, i, timeout)) != APR_SU CCESS) {
498 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
499 return rv;
500 }
501 break;
502 case SSL_ERROR_SYSCALL:
503 if (s == -1) {
504 if (APR_STATUS_IS_EPIPE(rv) || APR_STATUS_IS_ECONNRESET( rv)) {
505 con->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
506 return APR_EOF;
507 }
508 #if !defined(_WIN32)
509 else if (APR_STATUS_IS_EINTR(rv)) {
510 /* Interrupted by signal
511 */
512 continue;
513 }
514 #endif
515 }
516 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
517 return rv;
518 break;
519 case SSL_ERROR_SSL:
520 /* Probably caused by buffer missmatch */
521 rv = APR_EINVAL;
522 case SSL_ERROR_ZERO_RETURN:
523 if (s == 0) {
524 con->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
525 return APR_EOF;
526 }
527 /* Fall trough */
528 default:
529 con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
530 return rv;
531 break;
532 }
533 }
534 else {
535 *len = s;
536 break;
537 }
538 }
539 return APR_SUCCESS;
540 }
541
542 static apr_status_t APR_THREAD_FUNC
543 ssl_socket_sendv(apr_socket_t *sock,
544 const struct iovec *vec,
545 apr_int32_t nvec, apr_size_t *len)
546 {
547 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
548 apr_status_t rv;
549 apr_size_t written = 0;
550 apr_int32_t i;
551
552 for (i = 0; i < nvec; i++) {
553 apr_size_t rd = vec[i].iov_len;
554 if ((rv = ssl_socket_send((apr_socket_t *)con,
555 vec[i].iov_base, &rd)) != APR_SUCCESS) {
556 *len = written;
557 return rv;
558 }
559 written += rd;
560 }
561 *len = written;
562 return APR_SUCCESS;
563 }
564
565 static tcn_nlayer_t ssl_socket_layer = {
566 TCN_SOCKET_SSL,
567 ssl_cleanup,
568 ssl_socket_close,
569 ssl_socket_shutdown,
570 ssl_socket_opt_get,
571 ssl_socket_opt_set,
572 ssl_socket_timeout_get,
573 ssl_socket_timeout_set,
574 ssl_socket_send,
575 ssl_socket_sendv,
576 ssl_socket_recv
577 };
578
579
580 TCN_IMPLEMENT_CALL(jint, SSLSocket, attach)(TCN_STDARGS, jlong ctx,
581 jlong sock)
582 {
583 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
584 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
585 tcn_ssl_conn_t *con;
586 apr_os_sock_t oss;
587 apr_status_t rv;
588
589 UNREFERENCED(o);
590 TCN_ASSERT(ctx != 0);
591 TCN_ASSERT(sock != 0);
592
593 if (!s->sock)
594 return APR_ENOTSOCK;
595
596 if ((rv = apr_os_sock_get(&oss, s->sock)) != APR_SUCCESS)
597 return rv;
598 if (oss == APR_INVALID_SOCKET)
599 return APR_ENOTSOCK;
600
601 if ((con = ssl_create(e, c, s->pool)) == NULL)
602 return APR_EGENERAL;
603 con->sock = s->sock;
604
605 SSL_set_fd(con->ssl, (int)oss);
606 if (c->mode)
607 SSL_set_accept_state(con->ssl);
608 else
609 SSL_set_connect_state(con->ssl);
610 /* Change socket type */
611 s->net = &ssl_socket_layer;
612 s->opaque = con;
613
614 return APR_SUCCESS;
615 }
616
617 TCN_IMPLEMENT_CALL(jint, SSLSocket, renegotiate)(TCN_STDARGS,
618 jlong sock)
619 {
620 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
621 tcn_ssl_conn_t *con;
622 int retVal;
623 int ecode = SSL_ERROR_WANT_READ;
624 apr_status_t rv;
625 apr_interval_time_t timeout;
626
627 UNREFERENCED_STDARGS;
628 TCN_ASSERT(sock != 0);
629 con = (tcn_ssl_conn_t *)s->opaque;
630
631 /* Sequence to renegotiate is
632 * SSL_renegotiate()
633 * SSL_do_handshake()
634 * ssl->state = SSL_ST_ACCEPT
635 * SSL_do_handshake()
636 */
637
638 /* Toggle the renegotiation state to allow the new
639 * handshake to proceed.
640 */
641 con->reneg_state = RENEG_ALLOW;
642 retVal = SSL_renegotiate(con->ssl);
643 if (retVal <= 0)
644 return APR_EGENERAL;
645
646 retVal = SSL_do_handshake(con->ssl);
647 if (retVal <= 0)
648 return APR_EGENERAL;
649
650 if (SSL_get_state(con->ssl) != SSL_ST_OK) {
651 return APR_EGENERAL;
652 }
653 SSL_set_state(con->ssl, SSL_ST_ACCEPT);
654
655 apr_socket_timeout_get(con->sock, &timeout);
656 ecode = SSL_ERROR_WANT_READ;
657 while (ecode == SSL_ERROR_WANT_READ) {
658 retVal = SSL_do_handshake(con->ssl);
659 if (retVal <= 0) {
660 ecode = SSL_get_error(con->ssl, retVal);
661 if (ecode == SSL_ERROR_WANT_READ) {
662 if ((rv = wait_for_io_or_timeout(con, ecode, timeout)) != APR_SU CCESS)
663 return rv; /* Can't wait */
664 continue; /* It should be ok now */
665 }
666 else
667 return APR_EGENERAL;
668 } else
669 break;
670 }
671 con->reneg_state = RENEG_REJECT;
672
673 if (SSL_get_state(con->ssl) != SSL_ST_OK) {
674 return APR_EGENERAL;
675 }
676
677 return APR_SUCCESS;
678 }
679
680 TCN_IMPLEMENT_CALL(void, SSLSocket, setVerify)(TCN_STDARGS,
681 jlong sock,
682 jint cverify,
683 jint depth)
684 {
685 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
686 tcn_ssl_conn_t *con;
687 int verify = SSL_VERIFY_NONE;
688
689 UNREFERENCED_STDARGS;
690 TCN_ASSERT(sock != 0);
691 con = (tcn_ssl_conn_t *)s->opaque;
692
693 if (cverify == SSL_CVERIFY_UNSET)
694 cverify = SSL_CVERIFY_NONE;
695 if (depth > 0)
696 SSL_set_verify_depth(con->ssl, depth);
697
698 if (cverify == SSL_CVERIFY_REQUIRE)
699 verify |= SSL_VERIFY_PEER_STRICT;
700 if ((cverify == SSL_CVERIFY_OPTIONAL) ||
701 (cverify == SSL_CVERIFY_OPTIONAL_NO_CA))
702 verify |= SSL_VERIFY_PEER;
703
704 SSL_set_verify(con->ssl, verify, NULL);
705 }
706
707 #else
708 /* OpenSSL is not supported.
709 * Create empty stubs.
710 */
711
712 TCN_IMPLEMENT_CALL(jint, SSLSocket, handshake)(TCN_STDARGS, jlong sock)
713 {
714 UNREFERENCED_STDARGS;
715 UNREFERENCED(sock);
716 return (jint)APR_ENOTIMPL;
717 }
718
719 TCN_IMPLEMENT_CALL(jint, SSLSocket, attach)(TCN_STDARGS, jlong ctx,
720 jlong sock)
721 {
722 UNREFERENCED_STDARGS;
723 UNREFERENCED(ctx);
724 UNREFERENCED(sock);
725 return (jint)APR_ENOTIMPL;
726 }
727
728 TCN_IMPLEMENT_CALL(jint, SSLSocket, renegotiate)(TCN_STDARGS,
729 jlong sock)
730 {
731 UNREFERENCED_STDARGS;
732 UNREFERENCED(sock);
733 return (jint)APR_ENOTIMPL;
734 }
735
736 #endif
OLDNEW
« no previous file with comments | « c/sslinfo.c ('k') | c/sslutils.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698