X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fstream-ssl.c;h=f7112c3e14c2498990fd640757c0ec799eb23c0e;hb=cb034511802ff7516ca2a94da1e161965fb80ad0;hp=ca3d218bf95d59c54cd5f58637dad0c6eb7ecf3d;hpb=b5beaca19879c2b662fdb136262c81bf22f747da;p=openvswitch diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c index ca3d218b..f7112c3e 100644 --- a/lib/stream-ssl.c +++ b/lib/stream-ssl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -188,6 +188,7 @@ static int do_ssl_init(void); static bool ssl_wants_io(int ssl_error); static void ssl_close(struct stream *); static void ssl_clear_txbuf(struct ssl_stream *); +static void interpret_queued_ssl_error(const char *function); static int interpret_ssl_error(const char *function, int ret, int error, int *want); static DH *tmp_dh_callback(SSL *ssl, int is_export OVS_UNUSED, int keylength); @@ -279,6 +280,13 @@ new_ssl_stream(const char *name, int fd, enum session_type type, if (!verify_peer_cert || (bootstrap_ca_cert && type == CLIENT)) { SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); } + if (type == CLIENT) { + /* Grab SSL session information from the cache. */ + SSL_SESSION *session = shash_find_data(&client_sessions, name); + if (session && SSL_set_session(ssl, session) != 1) { + interpret_queued_ssl_error("SSL_set_session"); + } + } /* Create and return the ssl_stream. */ sslv = xmalloc(sizeof *sslv); @@ -463,12 +471,6 @@ ssl_cache_session(struct stream *stream) struct ssl_stream *sslv = ssl_stream_cast(stream); SSL_SESSION *session; - /* Statistics. */ - COVERAGE_INC(ssl_session); - if (SSL_session_reused(sslv->ssl)) { - COVERAGE_INC(ssl_session_reused); - } - /* Get session from stream. */ session = SSL_get1_session(sslv->ssl); if (session) { @@ -490,12 +492,6 @@ ssl_cache_session(struct stream *stream) } } } - } else { - /* There is no new session. This doesn't really make sense because - * this function is only called upon successful connection and there - * should always be a new session in that case. But I don't trust - * OpenSSL so I'd rather handle this case anyway. */ - ssl_flush_session(stream); } } @@ -522,15 +518,6 @@ ssl_connect(struct stream *stream) MSG_PEEK); } - /* Grab SSL session information from the cache. */ - if (sslv->type == CLIENT) { - SSL_SESSION *session = shash_find_data(&client_sessions, - stream_get_name(stream)); - if (session) { - SSL_set_session(sslv->ssl, session); - } - } - retval = (sslv->type == CLIENT ? SSL_connect(sslv->ssl) : SSL_accept(sslv->ssl)); if (retval != 1) { @@ -575,8 +562,10 @@ ssl_connect(struct stream *stream) VLOG_ERR("rejecting SSL connection during bootstrap race window"); return EPROTO; } else { - if (sslv->type == CLIENT) { - ssl_cache_session(stream); + /* Statistics. */ + COVERAGE_INC(ssl_session); + if (SSL_session_reused(sslv->ssl)) { + COVERAGE_INC(ssl_session_reused); } return 0; } @@ -598,6 +587,8 @@ ssl_close(struct stream *stream) * background. */ SSL_shutdown(sslv->ssl); + ssl_cache_session(stream); + /* SSL_shutdown() might have signaled an error, in which case we need to * flush it out of the OpenSSL error queue or the next OpenSSL operation * will falsely signal an error. */ @@ -608,6 +599,18 @@ ssl_close(struct stream *stream) free(sslv); } +static void +interpret_queued_ssl_error(const char *function) +{ + int queued_error = ERR_get_error(); + if (queued_error != 0) { + VLOG_WARN_RL(&rl, "%s: %s", + function, ERR_error_string(queued_error, NULL)); + } else { + VLOG_ERR_RL(&rl, "%s: SSL_ERROR_SSL without queued error", function); + } +} + static int interpret_ssl_error(const char *function, int ret, int error, int *want) @@ -664,17 +667,9 @@ interpret_ssl_error(const char *function, int ret, int error, } } - case SSL_ERROR_SSL: { - int queued_error = ERR_get_error(); - if (queued_error != 0) { - VLOG_WARN_RL(&rl, "%s: %s", - function, ERR_error_string(queued_error, NULL)); - } else { - VLOG_ERR_RL(&rl, "%s: SSL_ERROR_SSL without queued error", - function); - } + case SSL_ERROR_SSL: + interpret_queued_ssl_error(function); break; - } default: VLOG_ERR_RL(&rl, "%s: bad SSL error code %d", function, error);