00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00026 #include "platform.h"
00027 #include "internal.h"
00028 #include "session.h"
00029 #include "io_openssl.h"
00030
00031
00041 static int
00042 spdyf_next_protos_advertised_cb (SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg)
00043 {
00044 (void)ssl;
00045 (void)arg;
00046 static unsigned char npn_spdy3[] = {0x06,
00047 0x73,0x70,0x64,0x79,0x2f,0x33};
00048
00049 *out = npn_spdy3;
00050 *outlen = 7;
00051 return SSL_TLSEXT_ERR_OK;
00052 }
00053
00054
00055 void
00056 SPDYF_openssl_global_init()
00057 {
00058
00059
00060
00061 SSL_library_init();
00062
00063
00064 }
00065
00066
00067 void
00068 SPDYF_openssl_global_deinit()
00069 {
00070
00071
00072
00073
00074 }
00075
00076
00077 int
00078 SPDYF_openssl_init(struct SPDY_Daemon *daemon)
00079 {
00080 int options;
00081
00082 if(NULL == (daemon->io_context = SSL_CTX_new(TLSv1_server_method())))
00083 {
00084 SPDYF_DEBUG("Couldn't create ssl context");
00085 return SPDY_NO;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 options = SSL_OP_NO_TICKET;
00095 #ifdef SSL_OP_NO_COMPRESSION
00096 options |= SSL_OP_NO_COMPRESSION;
00097 #elif OPENSSL_VERSION_NUMBER >= 0x00908000L
00098 sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
00099 #endif
00100
00101 SSL_CTX_set_options(daemon->io_context, options);
00102 if(1 != SSL_CTX_use_certificate_file(daemon->io_context, daemon->certfile , SSL_FILETYPE_PEM))
00103 {
00104 SPDYF_DEBUG("Couldn't load the cert file");
00105 SSL_CTX_free(daemon->io_context);
00106 return SPDY_NO;
00107 }
00108 if(1 != SSL_CTX_use_PrivateKey_file(daemon->io_context, daemon->keyfile, SSL_FILETYPE_PEM))
00109 {
00110 SPDYF_DEBUG("Couldn't load the name file");
00111 SSL_CTX_free(daemon->io_context);
00112 return SPDY_NO;
00113 }
00114 SSL_CTX_set_next_protos_advertised_cb(daemon->io_context, &spdyf_next_protos_advertised_cb, NULL);
00115
00116 if (1 != SSL_CTX_set_cipher_list(daemon->io_context, "RC4-SHA"))
00117 {
00118 SPDYF_DEBUG("Couldn't set the desired cipher list");
00119 SSL_CTX_free(daemon->io_context);
00120 return SPDY_NO;
00121 }
00122
00123 return SPDY_YES;
00124 }
00125
00126
00127 void
00128 SPDYF_openssl_deinit(struct SPDY_Daemon *daemon)
00129 {
00130 SSL_CTX_free(daemon->io_context);
00131 }
00132
00133
00134 int
00135 SPDYF_openssl_new_session(struct SPDY_Session *session)
00136 {
00137 int ret;
00138
00139 if(NULL == (session->io_context = SSL_new(session->daemon->io_context)))
00140 {
00141 SPDYF_DEBUG("Couldn't create ssl structure");
00142 return SPDY_NO;
00143 }
00144 if(1 != (ret = SSL_set_fd(session->io_context, session->socket_fd)))
00145 {
00146 SPDYF_DEBUG("SSL_set_fd %i",ret);
00147 SSL_free(session->io_context);
00148 session->io_context = NULL;
00149 return SPDY_NO;
00150 }
00151
00152
00153
00154 if(1 != (ret = SSL_accept(session->io_context)))
00155 {
00156 SPDYF_DEBUG("SSL_accept %i",ret);
00157 SSL_free(session->io_context);
00158 session->io_context = NULL;
00159 return SPDY_NO;
00160 }
00161
00162
00163
00164
00165
00166 return SPDY_YES;
00167 }
00168
00169
00170 void
00171 SPDYF_openssl_close_session(struct SPDY_Session *session)
00172 {
00173
00174
00175
00176
00177
00178 SSL_shutdown(session->io_context);
00179
00180 SSL_free(session->io_context);
00181 }
00182
00183
00184 int
00185 SPDYF_openssl_recv(struct SPDY_Session *session,
00186 void * buffer,
00187 size_t size)
00188 {
00189 int ret;
00190 int n = SSL_read(session->io_context,
00191 buffer,
00192 size);
00193
00194 if (n <= 0)
00195 {
00196 ret = SSL_get_error(session->io_context, n);
00197 switch(ret)
00198 {
00199 case SSL_ERROR_ZERO_RETURN:
00200 return 0;
00201
00202 case SSL_ERROR_WANT_READ:
00203 case SSL_ERROR_WANT_WRITE:
00204 return SPDY_IO_ERROR_AGAIN;
00205
00206 case SSL_ERROR_SYSCALL:
00207 if(EINTR == errno)
00208 return SPDY_IO_ERROR_AGAIN;
00209
00210 default:
00211 return SPDY_IO_ERROR_ERROR;
00212 }
00213 }
00214
00215 return n;
00216 }
00217
00218
00219 int
00220 SPDYF_openssl_send(struct SPDY_Session *session,
00221 const void * buffer,
00222 size_t size)
00223 {
00224 int ret;
00225
00226 int n = SSL_write(session->io_context,
00227 buffer,
00228 size);
00229
00230 if (n <= 0)
00231 {
00232 ret = SSL_get_error(session->io_context, n);
00233 switch(ret)
00234 {
00235 case SSL_ERROR_ZERO_RETURN:
00236 return 0;
00237
00238 case SSL_ERROR_WANT_READ:
00239 case SSL_ERROR_WANT_WRITE:
00240 return SPDY_IO_ERROR_AGAIN;
00241
00242 case SSL_ERROR_SYSCALL:
00243 if(EINTR == errno)
00244 return SPDY_IO_ERROR_AGAIN;
00245
00246 default:
00247 return SPDY_IO_ERROR_ERROR;
00248 }
00249 }
00250
00251 return n;
00252 }
00253
00254
00255 int
00256 SPDYF_openssl_is_pending(struct SPDY_Session *session)
00257 {
00258
00259
00260
00261
00262 return SSL_pending(session->io_context) > 0 ? SPDY_YES : SPDY_NO;
00263 }
00264
00265
00266 int
00267 SPDYF_openssl_before_write(struct SPDY_Session *session)
00268 {
00269 (void)session;
00270
00271 return SPDY_YES;
00272 }
00273
00274
00275 int
00276 SPDYF_openssl_after_write(struct SPDY_Session *session, int was_written)
00277 {
00278 (void)session;
00279
00280 return was_written;
00281 }