const SSL_METHOD *sycTLSv1_1_server_method(void) { const SSL_METHOD *result; Debug("TLSv1_1_server_method()"); result = TLSv1_1_server_method(); Debug1("TLSv1_1_server_method() -> %p", result); return result; }
void ssl_init() { SSL_library_init(); SSL_load_error_strings(); BGPTLS_sess_server.psMethod = TLSv1_1_server_method(); //Or client method when putting this code on the client. BGPTLS_sess_server.psCTX = SSL_CTX_new(BGPTLS_sess_server.psMethod); }
void Context::createSSLContext() { if (SSLManager::isFIPSEnabled()) { _pSSLContext = SSL_CTX_new(TLSv1_method()); } else { switch (_usage) { case CLIENT_USE: _pSSLContext = SSL_CTX_new(SSLv23_client_method()); break; case SERVER_USE: _pSSLContext = SSL_CTX_new(SSLv23_server_method()); break; #if defined(SSL_OP_NO_TLSv1) && !defined(OPENSSL_NO_TLS1) case TLSV1_CLIENT_USE: _pSSLContext = SSL_CTX_new(TLSv1_client_method()); break; case TLSV1_SERVER_USE: _pSSLContext = SSL_CTX_new(TLSv1_server_method()); break; #endif #if defined(SSL_OP_NO_TLSv1_1) && !defined(OPENSSL_NO_TLS1) /* SSL_OP_NO_TLSv1_1 is defined in ssl.h if the library version supports TLSv1.1. * OPENSSL_NO_TLS1 is defined in opensslconf.h or on the compiler command line * if TLS1.x was removed at OpenSSL library build time via Configure options. */ case TLSV1_1_CLIENT_USE: _pSSLContext = SSL_CTX_new(TLSv1_1_client_method()); break; case TLSV1_1_SERVER_USE: _pSSLContext = SSL_CTX_new(TLSv1_1_server_method()); break; #endif #if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1) case TLSV1_2_CLIENT_USE: _pSSLContext = SSL_CTX_new(TLSv1_2_client_method()); break; case TLSV1_2_SERVER_USE: _pSSLContext = SSL_CTX_new(TLSv1_2_server_method()); break; #endif default: throw Poco::InvalidArgumentException("Invalid or unsupported usage"); } } if (!_pSSLContext) { unsigned long err = ERR_get_error(); throw SSLException("Cannot create SSL_CTX object", ERR_error_string(err, 0)); } SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPassphraseCallback); Utility::clearErrorStack(); SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL); }
static const SSL_METHOD *tls1_get_server_method(int ver) { if (ver == TLS1_2_VERSION) return TLSv1_2_server_method(); if (ver == TLS1_1_VERSION) return TLSv1_1_server_method(); if (ver == TLS1_VERSION) return TLSv1_server_method(); return NULL; }
bool VSslServer::doOpen() { VLock lock(stateOpenCs); // gilgil temp 2014.03.14 // // Set server method // LOG_DEBUG("method=%s", qPrintable(methodType.str())); switch (methodType) { #ifdef _WIN32 // Linux openssl does not support SSLv2_server_method case VSslMethodType::mtSSLv2 : m_meth = (SSL_METHOD*)SSLv2_server_method(); break; #endif // _WIN32 case VSslMethodType::mtSSLv3 : m_meth = (SSL_METHOD*)SSLv3_server_method(); break; case VSslMethodType::mtSSLv23 : m_meth = (SSL_METHOD*)SSLv23_server_method(); break; case VSslMethodType::mtTLSv1 : m_meth = (SSL_METHOD*)TLSv1_server_method(); break; case VSslMethodType::mtTLSv1_1 : m_meth = (SSL_METHOD*)TLSv1_1_server_method(); break; case VSslMethodType::mtTLSv1_2 : m_meth = (SSL_METHOD*)TLSv1_2_server_method(); break; case VSslMethodType::mtDTLSv1 : m_meth = (SSL_METHOD*)DTLSv1_server_method(); break; case VSslMethodType::mtNone : default : SET_ERROR(VSslError, QString("client method error(%1)").arg(methodType.str()), VSslError::INVALID_SSL_METHOD); return false; } m_ctx = SSL_CTX_new(m_meth); if (!SSL_CTX_set_tlsext_servername_callback(m_ctx, ssl_servername_cb)) { LOG_ERROR("SSL_CTX_set_tlsext_servername_callback return false"); } if (!SSL_CTX_set_tlsext_servername_arg(m_ctx, this)) { LOG_ERROR("SSL_CTX_set_tlsext_servername_arg return false"); } if (defaultKeyCrtFileName != "") { QString fileName = certificatePath; QFileInfo fi(fileName); // if (!fi.isAbsolute()) fileName = VApp::_filePath() + fileName; // gilgil temp 2014.12.25 if (!fi.isAbsolute()) fileName = QCoreApplication::applicationDirPath() + QDir::separator() + fileName; // gilgil temp 2014.12.25 if (!fileName.endsWith('/') && !fileName.endsWith('\\')) { fileName += QDir::separator(); } fileName += defaultKeyCrtFileName; if (!setup(fileName)) return false; } if (!VTcpServer::doOpen()) return false; return true; }
const SSL_METHOD *anubis_string_to_SSL_METOHD(const char *method, int role) { if(!method) return NULL; if(!strcasecmp(method, "SSLv23")) return role == ANUBIS_ROLE_SERVER ? SSLv23_server_method() : role == ANUBIS_ROLE_CLIENT ? SSLv23_client_method() : NULL; #ifndef OPENSSL_NO_SSL2_METHOD if(!strcasecmp(method, "SSLv2")) return role == ANUBIS_ROLE_SERVER ? SSLv3_server_method() : role == ANUBIS_ROLE_CLIENT ? SSLv3_client_method() : NULL; #endif #ifndef OPENSSL_NO_SSL3_METHOD if(!strcasecmp(method, "SSLv3")) return role == ANUBIS_ROLE_SERVER ? SSLv3_server_method() : role == ANUBIS_ROLE_CLIENT ? SSLv3_client_method() : NULL; #endif if(!strcasecmp(method, "TLSv1.0")) return role == ANUBIS_ROLE_SERVER ? TLSv1_server_method() : role == ANUBIS_ROLE_CLIENT ? TLSv1_client_method() : NULL; #if OPENSSL_VERSION_NUMBER >= 0x10001000L if(!strcasecmp(method, "TLSv1.1")) return role == ANUBIS_ROLE_SERVER ? TLSv1_1_server_method() : role == ANUBIS_ROLE_CLIENT ? TLSv1_1_client_method() : NULL; if(!strcasecmp(method, "TLSv1.2")) return role == ANUBIS_ROLE_SERVER ? TLSv1_2_server_method() : role == ANUBIS_ROLE_CLIENT ? TLSv1_2_client_method() : NULL; #endif /* if(!strcasecmp(method, "DTLS1.0")) return role == ANUBIS_ROLE_SERVER ? DTLSv1_server_method() : role == ANUBIS_ROLE_CLIENT ? DTLSv1_client_method() : NULL; if(!strcasecmp(method, "DTLS1.2")) return role == ANUBIS_ROLE_SERVER ? DTLSv1_2_server_method() : role == ANUBIS_ROLE_CLIENT ? DTLSv1_2_client_method() : NULL; if(!strcasecmp(method, "DTLS")) return role == ANUBIS_ROLE_SERVER ? DTLS_server_method() : role == ANUBIS_ROLE_CLIENT ? DTLS_client_method() : NULL; */ return NULL; }//end anubis_string_to_SSL_METOHD
static const SSL_METHOD *swSSL_get_method(int method) { switch (method) { #ifndef OPENSSL_NO_SSL3_METHOD case SW_SSLv3_METHOD: return SSLv3_method(); case SW_SSLv3_SERVER_METHOD: return SSLv3_server_method(); case SW_SSLv3_CLIENT_METHOD: return SSLv3_client_method(); #endif case SW_SSLv23_SERVER_METHOD: return SSLv23_server_method(); case SW_SSLv23_CLIENT_METHOD: return SSLv23_client_method(); case SW_TLSv1_METHOD: return TLSv1_method(); case SW_TLSv1_SERVER_METHOD: return TLSv1_server_method(); case SW_TLSv1_CLIENT_METHOD: return TLSv1_client_method(); #ifdef TLS1_1_VERSION case SW_TLSv1_1_METHOD: return TLSv1_1_method(); case SW_TLSv1_1_SERVER_METHOD: return TLSv1_1_server_method(); case SW_TLSv1_1_CLIENT_METHOD: return TLSv1_1_client_method(); #endif #ifdef TLS1_2_VERSION case SW_TLSv1_2_METHOD: return TLSv1_2_method(); case SW_TLSv1_2_SERVER_METHOD: return TLSv1_2_server_method(); case SW_TLSv1_2_CLIENT_METHOD: return TLSv1_2_client_method(); #endif case SW_DTLSv1_METHOD: return DTLSv1_method(); case SW_DTLSv1_SERVER_METHOD: return DTLSv1_server_method(); case SW_DTLSv1_CLIENT_METHOD: return DTLSv1_client_method(); case SW_SSLv23_METHOD: default: return SSLv23_method(); } return SSLv23_method(); }
static const SSL_METHOD * ssl23_get_server_method(int ver) { if (ver == SSL3_VERSION) return (SSLv3_server_method()); else if (ver == TLS1_VERSION) return (TLSv1_server_method()); else if (ver == TLS1_1_VERSION) return (TLSv1_1_server_method()); else if (ver == TLS1_2_VERSION) return (TLSv1_2_server_method()); else return (NULL); }
static const SSL_METHOD *ssl23_get_server_method(int ver) { #ifndef OPENSSL_NO_SSL3 if (ver == SSL3_VERSION) return(SSLv3_server_method()); #endif if (ver == TLS1_VERSION) return(TLSv1_server_method()); else if (ver == TLS1_1_VERSION) return(TLSv1_1_server_method()); else if (ver == TLS1_2_VERSION) return(TLSv1_2_server_method()); else return(NULL); }
static const SSL_METHOD *tls1_get_server_method(int ver) { if (ver == TLS_ANY_VERSION) return TLS_server_method(); if (ver == TLS1_2_VERSION) return TLSv1_2_server_method(); if (ver == TLS1_1_VERSION) return TLSv1_1_server_method(); if (ver == TLS1_VERSION) return TLSv1_server_method(); #ifndef OPENSSL_NO_SSL3 if (ver == SSL3_VERSION) return (SSLv3_server_method()); #endif return NULL; }
SSL_CTX* EdSSLContext::buildServerCtx(int sslmethod, const char* certfile, const char* privkeyfile) { const SSL_METHOD *method; switch (sslmethod) { case SSL_VER_TLSV1: method = TLSv1_server_method(); break; case SSL_VER_TLSV11: method = TLSv1_1_server_method(); break; case SSL_VER_V23: method = SSLv23_server_method(); break; case SSL_VER_V3: method = SSLv3_server_method(); break; case SSL_VER_DTLSV1: method = DTLSv1_server_method(); break; default: method = NULL; break; } if (method == NULL) return NULL; SSL_CTX* pctx = SSL_CTX_new(method); int ret; ret = SSL_CTX_use_certificate_file(pctx, certfile, SSL_FILETYPE_PEM); dbgd("set cert file, ret=%d", ret); ret = SSL_CTX_use_PrivateKey_file(pctx, privkeyfile, SSL_FILETYPE_PEM); dbgd("set key file, ret=%d", ret); if (!SSL_CTX_check_private_key(pctx)) { dbge("### private key check error......"); SSL_CTX_free(pctx); return NULL; } return pctx; }
static const SSL_METHOD *swSSL_get_method(int method) { switch (method) { case SW_SSLv3_METHOD: return SSLv3_method(); case SW_SSLv3_SERVER_METHOD: return SSLv3_server_method(); case SW_SSLv3_CLIENT_METHOD: return SSLv3_client_method(); case SW_SSLv23_SERVER_METHOD: return SSLv23_server_method(); case SW_SSLv23_CLIENT_METHOD: return SSLv23_client_method(); case SW_TLSv1_METHOD: return TLSv1_method(); case SW_TLSv1_SERVER_METHOD: return TLSv1_server_method(); case SW_TLSv1_CLIENT_METHOD: return TLSv1_client_method(); case SW_TLSv1_1_METHOD: return TLSv1_1_method(); case SW_TLSv1_1_SERVER_METHOD: return TLSv1_1_server_method(); case SW_TLSv1_1_CLIENT_METHOD: return TLSv1_1_client_method(); case SW_TLSv1_2_METHOD: return TLSv1_2_method(); case SW_TLSv1_2_SERVER_METHOD: return TLSv1_2_server_method(); case SW_TLSv1_2_CLIENT_METHOD: return TLSv1_2_client_method(); case SW_DTLSv1_METHOD: return DTLSv1_method(); case SW_DTLSv1_SERVER_METHOD: return DTLSv1_server_method(); case SW_DTLSv1_CLIENT_METHOD: return DTLSv1_client_method(); case SW_SSLv23_METHOD: default: return SSLv23_method(); } return SSLv23_method(); }
bud_error_t bud_config_new_ssl_ctx(bud_config_t* config, bud_context_t* context) { SSL_CTX* ctx; int ecdh_nid; EC_KEY* ecdh; bud_error_t err; int options; int r; const char* ticket_key; size_t max_len; if (context->backend != NULL) { if (context->backend->keepalive == -1) context->backend->keepalive = kBudDefaultKeepalive; r = bud_config_str_to_addr(context->backend->host, context->backend->port, &context->backend->addr); if (r != 0) return bud_error_num(kBudErrPton, r); } /* Decode ticket_key */ ticket_key = context->ticket_key == NULL ? config->frontend.ticket_key : context->ticket_key; if (ticket_key != NULL) { max_len = sizeof(context->ticket_key_storage); if (bud_base64_decode(context->ticket_key_storage, max_len, ticket_key, strlen(ticket_key)) < max_len) { return bud_error(kBudErrSmallTicketKey); } } /* Choose method, tlsv1_2 by default */ if (config->frontend.method == NULL) { if (strcmp(config->frontend.security, "tls1.1") == 0) config->frontend.method = TLSv1_1_server_method(); else if (strcmp(config->frontend.security, "tls1.0") == 0) config->frontend.method = TLSv1_server_method(); else if (strcmp(config->frontend.security, "tls1.2") == 0) config->frontend.method = TLSv1_2_server_method(); else if (strcmp(config->frontend.security, "ssl3") == 0) config->frontend.method = SSLv3_server_method(); else config->frontend.method = SSLv23_server_method(); } ctx = SSL_CTX_new(config->frontend.method); if (ctx == NULL) return bud_error_str(kBudErrNoMem, "SSL_CTX"); /* Disable sessions, they won't work with cluster anyway */ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); if (config->frontend.max_send_fragment) SSL_CTX_set_max_send_fragment(ctx, config->frontend.max_send_fragment); if (ticket_key != NULL) { SSL_CTX_set_tlsext_ticket_keys(ctx, context->ticket_key_storage, sizeof(context->ticket_key_storage)); } /* ECDH curve selection */ if (context->ecdh != NULL || config->frontend.ecdh != NULL) { if (context->ecdh != NULL) ecdh_nid = OBJ_sn2nid(context->ecdh); else ecdh_nid = OBJ_sn2nid(config->frontend.ecdh); if (ecdh_nid == NID_undef) { ecdh = NULL; err = bud_error_str(kBudErrECDHNotFound, context->ecdh == NULL ? config->frontend.ecdh : context->ecdh); goto fatal; } ecdh = EC_KEY_new_by_curve_name(ecdh_nid); if (ecdh == NULL) { err = bud_error_str(kBudErrNoMem, "EC_KEY"); goto fatal; } SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); SSL_CTX_set_tmp_ecdh(ctx, ecdh); EC_KEY_free(ecdh); } ecdh = NULL; /* Cipher suites */ if (context->ciphers != NULL) SSL_CTX_set_cipher_list(ctx, context->ciphers); else if (config->frontend.ciphers != NULL) SSL_CTX_set_cipher_list(ctx, config->frontend.ciphers); /* Disable SSL2 */ options = SSL_OP_NO_SSLv2 | SSL_OP_ALL; if (!config->frontend.ssl3) options |= SSL_OP_NO_SSLv3; if (config->frontend.server_preference) options |= SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_CTX_set_options(ctx, options); #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB if (config->context_count != 0) { SSL_CTX_set_tlsext_servername_callback(ctx, bud_config_select_sni_context); SSL_CTX_set_tlsext_servername_arg(ctx, config); } #endif /* SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */ #ifdef OPENSSL_NPN_NEGOTIATED context->npn_line = bud_config_encode_npn(config, context->npn, &context->npn_line_len, &err); if (!bud_is_ok(err)) goto fatal; if (context->npn_line != NULL) { SSL_CTX_set_next_protos_advertised_cb(ctx, bud_config_advertise_next_proto, context); } #else /* !OPENSSL_NPN_NEGOTIATED */ err = bud_error(kBudErrNPNNotSupported); goto fatal; #endif /* OPENSSL_NPN_NEGOTIATED */ SSL_CTX_set_tlsext_status_cb(ctx, bud_client_stapling_cb); context->ctx = ctx; return bud_ok(); fatal: if (ecdh != NULL) EC_KEY_free(ecdh); SSL_CTX_free(ctx); return err; }
static int openssl_ssl_ctx_new(lua_State*L) { const char* meth = luaL_optstring(L, 1, "TLSv1"); #if OPENSSL_VERSION_NUMBER >= 0x01000000L const #endif SSL_METHOD* method = NULL; const char* ciphers; SSL_CTX* ctx; if (strcmp(meth, "SSLv3") == 0) method = SSLv3_method(); /* SSLv3 */ else if (strcmp(meth, "SSLv3_server") == 0) method = SSLv3_server_method(); /* SSLv3 */ else if (strcmp(meth, "SSLv3_client") == 0) method = SSLv3_client_method(); /* SSLv3 */ else if (strcmp(meth, "SSLv23") == 0) method = SSLv23_method(); /* SSLv3 but can rollback to v2 */ else if (strcmp(meth, "SSLv23_server") == 0) method = SSLv23_server_method(); /* SSLv3 but can rollback to v2 */ else if (strcmp(meth, "SSLv23_client") == 0) method = SSLv23_client_method(); /* SSLv3 but can rollback to v2 */ else if (strcmp(meth, "TLSv1_1") == 0) method = TLSv1_1_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_1_server") == 0) method = TLSv1_1_server_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_1_client") == 0) method = TLSv1_1_client_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_2") == 0) method = TLSv1_2_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_2_server") == 0) method = TLSv1_2_server_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_2_client") == 0) method = TLSv1_2_client_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1") == 0) method = TLSv1_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_server") == 0) method = TLSv1_server_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_client") == 0) method = TLSv1_client_method(); /* TLSv1.0 */ else if (strcmp(meth, "DTLSv1") == 0) method = DTLSv1_method(); /* DTLSv1.0 */ else if (strcmp(meth, "DTLSv1_server") == 0) method = DTLSv1_server_method(); /* DTLSv1.0 */ else if (strcmp(meth, "DTLSv1_client") == 0) method = DTLSv1_client_method(); /* DTLSv1.0 */ #ifndef OPENSSL_NO_SSL2 #if OPENSSL_VERSION_NUMBER < 0x10100000L else if (strcmp(meth, "SSLv2") == 0) method = SSLv2_method(); /* SSLv2 */ else if (strcmp(meth, "SSLv2_server") == 0) method = SSLv2_server_method(); /* SSLv2 */ else if (strcmp(meth, "SSLv2_client") == 0) method = SSLv2_client_method(); #endif #ifdef LOAD_SSL_CUSTOM LOAD_SSL_CUSTOM #endif #endif else luaL_error(L, "#1:%s not supported\n" "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n", "default is SSLv3", meth); ciphers = luaL_optstring(L, 2, SSL_DEFAULT_CIPHER_LIST); ctx = SSL_CTX_new(method); if (!ctx) luaL_error(L, "#1:%s not supported\n" "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n", "default is SSLv3", meth); openssl_newvalue(L, ctx); SSL_CTX_set_cipher_list(ctx, ciphers); PUSH_OBJECT(ctx, "openssl.ssl_ctx"); SSL_CTX_set_app_data(ctx, L); return 1; }
bud_error_t bud_config_new_ssl_ctx(bud_config_t* config, bud_context_t* context) { SSL_CTX* ctx; bud_error_t err; int options; /* Choose method, tlsv1_2 by default */ if (config->frontend.method == NULL) { if (strcmp(config->frontend.security, "tls1.1") == 0) config->frontend.method = TLSv1_1_server_method(); else if (strcmp(config->frontend.security, "tls1.0") == 0) config->frontend.method = TLSv1_server_method(); else if (strcmp(config->frontend.security, "tls1.2") == 0) config->frontend.method = TLSv1_2_server_method(); else if (strcmp(config->frontend.security, "ssl3") == 0) config->frontend.method = SSLv3_server_method(); else config->frontend.method = SSLv23_server_method(); } ctx = SSL_CTX_new(config->frontend.method); if (ctx == NULL) return bud_error_str(kBudErrNoMem, "SSL_CTX"); SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL | SSL_SESS_CACHE_NO_AUTO_CLEAR); if (context->ciphers != NULL) SSL_CTX_set_cipher_list(ctx, context->ciphers); else if (config->frontend.ciphers != NULL) SSL_CTX_set_cipher_list(ctx, config->frontend.ciphers); /* Disable SSL2 */ options = SSL_OP_NO_SSLv2 | SSL_OP_ALL; if (!config->frontend.ssl3) options |= SSL_OP_NO_SSLv3; if (config->frontend.server_preference) options |= SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_CTX_set_options(ctx, options); #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB if (config->context_count != 0) { SSL_CTX_set_tlsext_servername_callback(ctx, bud_config_select_sni_context); SSL_CTX_set_tlsext_servername_arg(ctx, config); } #endif /* SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */ #ifdef OPENSSL_NPN_NEGOTIATED context->npn_line = bud_config_encode_npn(config, context->npn, &context->npn_line_len, &err); if (!bud_is_ok(err)) goto fatal; if (context->npn_line != NULL) { SSL_CTX_set_next_protos_advertised_cb(ctx, bud_config_advertise_next_proto, context); } #else /* !OPENSSL_NPN_NEGOTIATED */ err = bud_error(kBudErrNPNNotSupported); goto fatal; #endif /* OPENSSL_NPN_NEGOTIATED */ SSL_CTX_set_tlsext_status_cb(ctx, bud_client_stapling_cb); context->ctx = ctx; return bud_ok(); fatal: SSL_CTX_free(ctx); return err; }
static const SSL_METHOD *get_method(int protocol, int type) { const SSL_METHOD *method = NULL; caml_enter_blocking_section(); switch (protocol) { case 0: switch (type) { case 0: method = SSLv23_client_method(); break; case 1: method = SSLv23_server_method(); break; case 2: method = SSLv23_method(); break; } break; case 1: switch (type) { case 0: method = SSLv3_client_method(); break; case 1: method = SSLv3_server_method(); break; case 2: method = SSLv3_method(); break; } break; case 2: switch (type) { case 0: method = TLSv1_client_method(); break; case 1: method = TLSv1_server_method(); break; case 2: method = TLSv1_method(); break; } break; case 3: #ifdef HAVE_TLS11 switch (type) { case 0: method = TLSv1_1_client_method(); break; case 1: method = TLSv1_1_server_method(); break; case 2: method = TLSv1_1_method(); break; } #endif break; case 4: #ifdef HAVE_TLS12 switch (type) { case 0: method = TLSv1_2_client_method(); break; case 1: method = TLSv1_2_server_method(); break; case 2: method = TLSv1_2_method(); break; } #endif break; default: caml_leave_blocking_section(); caml_invalid_argument("Unknown method (this should not have happened, please report)."); break; } caml_leave_blocking_section(); if (method == NULL) caml_raise_constant(*caml_named_value("ssl_exn_method_error")); return method; }
int ssl23_get_client_hello(SSL *s) { char buf_space[11]; /* Request this many bytes in initial read. * We can detect SSL 3.0/TLS 1.0 Client Hellos * ('type == 3') correctly only when the following * is in a single record, which is not guaranteed by * the protocol specification: * Byte Content * 0 type \ * 1/2 version > record header * 3/4 length / * 5 msg_type \ * 6-8 length > Client Hello message * 9/10 client_version / */ char *buf = &(buf_space[0]); unsigned char *p, *d, *d_len, *dd; unsigned int i; unsigned int csl, sil, cl; int n = 0, j; int type = 0; int v[2]; if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { /* read the initial header */ v[0] = v[1] = 0; if (!ssl3_setup_buffers(s)) goto err; n = ssl23_read_bytes(s, sizeof buf_space); if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */ p = s->packet; memcpy(buf, p, n); if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { /* * SSLv2 header */ if ((p[3] == 0x00) && (p[4] == 0x02)) { v[0] = p[3]; v[1] = p[4]; /* SSLv2 */ if (!(s->options & SSL_OP_NO_SSLv2)) type = 1; } else if (p[3] == SSL3_VERSION_MAJOR) { v[0] = p[3]; v[1] = p[4]; /* SSLv3/TLSv1 */ if (p[4] >= TLS1_VERSION_MINOR) { if (p[4] >= TLS1_2_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_2)) { s->version = TLS1_2_VERSION; s->state = SSL23_ST_SR_CLNT_HELLO_B; } else if (p[4] >= TLS1_1_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_1)) { s->version = TLS1_1_VERSION; /* type=2; */ /* done later to survive restarts */ s->state = SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_TLSv1)) { s->version = TLS1_VERSION; /* type=2; */ /* done later to survive restarts */ s->state = SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version = SSL3_VERSION; /* type=2; */ s->state = SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_SSLv2)) { type = 1; } } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version = SSL3_VERSION; /* type=2; */ s->state = SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_SSLv2)) type = 1; } } else if ((p[0] == SSL3_RT_HANDSHAKE) && (p[1] == SSL3_VERSION_MAJOR) && (p[5] == SSL3_MT_CLIENT_HELLO) && ((p[3] == 0 && p[4] < 5 /* silly record length? */) || (p[9] >= p[1]))) { /* * SSLv3 or tls1 header */ v[0] = p[1]; /* major version (= SSL3_VERSION_MAJOR) */ /* We must look at client_version inside the Client Hello message * to get the correct minor version. * However if we have only a pathologically small fragment of the * Client Hello message, this would be difficult, and we'd have * to read more records to find out. * No known SSL 3.0 client fragments ClientHello like this, * so we simply assume TLS 1.0 to avoid protocol version downgrade * attacks. */ if (p[3] == 0 && p[4] < 6) { #if 0 SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_SMALL); goto err; #else v[1] = TLS1_VERSION_MINOR; #endif } /* if major version number > 3 set minor to a value * which will use the highest version 3 we support. * If TLS 2.0 ever appears we will need to revise * this.... */ else if (p[9] > SSL3_VERSION_MAJOR) v[1] = 0xff; else v[1] = p[10]; /* minor version according to client_version */ if (v[1] >= TLS1_VERSION_MINOR) { if (v[1] >= TLS1_2_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_2)) { s->version = TLS1_2_VERSION; type = 3; } else if (v[1] >= TLS1_1_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_1)) { s->version = TLS1_1_VERSION; type = 3; } else if (!(s->options & SSL_OP_NO_TLSv1)) { s->version = TLS1_VERSION; type = 3; } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version = SSL3_VERSION; type = 3; } } else { /* client requests SSL 3.0 */ if (!(s->options & SSL_OP_NO_SSLv3)) { s->version = SSL3_VERSION; type = 3; } else if (!(s->options & SSL_OP_NO_TLSv1)) { /* we won't be able to use TLS of course, * but this will send an appropriate alert */ s->version = TLS1_VERSION; type = 3; } } } else if ((strncmp("GET ", (char *)p, 4) == 0) || (strncmp("POST ",(char *)p, 5) == 0) || (strncmp("HEAD ",(char *)p, 5) == 0) || (strncmp("PUT ", (char *)p, 4) == 0)) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTP_REQUEST); goto err; } else if (strncmp("CONNECT", (char *)p, 7) == 0) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTPS_PROXY_REQUEST); goto err; } } if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { /* we have SSLv3/TLSv1 in an SSLv2 header * (other cases skip this state) */ type = 2; p = s->packet; v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ v[1] = p[4]; n = ((p[0] & 0x7f) << 8) | p[1]; if (n > (1024 * 4)) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_LARGE); goto err; } j = ssl23_read_bytes(s, n + 2); if (j <= 0) return (j); ssl3_finish_mac(s, s->packet + 2, s->packet_length - 2); if (s->msg_callback) s->msg_callback(0, SSL2_VERSION, 0, s->packet + 2, s->packet_length-2, s, s->msg_callback_arg); p = s->packet; p += 5; n2s(p, csl); n2s(p, sil); n2s(p, cl); d = (unsigned char *)s->init_buf->data; if ((csl + sil + cl + 11) != s->packet_length) { /* * We can't have TLS extensions in SSL 2.0 format * Client Hello, can we ? Error condition should be * '>' otherwise */ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH); goto err; } /* record header: msg_type ... */ *(d++) = SSL3_MT_CLIENT_HELLO; /* ... and length (actual value will be written later) */ d_len = d; d += 3; /* client_version */ *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ *(d++) = v[1]; /* lets populate the random area */ /* get the challenge_length */ i = (cl > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : cl; memset(d, 0, SSL3_RANDOM_SIZE); memcpy(&(d[SSL3_RANDOM_SIZE - i]), &(p[csl + sil]), i); d += SSL3_RANDOM_SIZE; /* no session-id reuse */ *(d++) = 0; /* ciphers */ j = 0; dd = d; d += 2; for (i = 0; i < csl; i += 3) { if (p[i] != 0) continue; *(d++) = p[i + 1]; *(d++) = p[i + 2]; j += 2; } s2n(j, dd); /* COMPRESSION */ *(d++) = 1; *(d++) = 0; #if 0 /* copy any remaining data with may be extensions */ p = p + csl + sil + cl; while (p < s->packet + s->packet_length) { *(d++)=*(p++); } #endif i = (d - (unsigned char *)s->init_buf->data) - 4; l2n3((long)i, d_len); /* get the data reused from the init_buf */ s->s3->tmp.reuse_message = 1; s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; s->s3->tmp.message_size = i; } /* imaginary new state (for program structure): */ /* s->state = SSL23_SR_CLNT_HELLO_C */ if (type == 1) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); goto err; } if ((type == 2) || (type == 3)) { /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */ if (!ssl_init_wbio_buffer(s, 1)) goto err; /* we are in this state */ s->state = SSL3_ST_SR_CLNT_HELLO_A; if (type == 3) { /* put the 'n' bytes we have read into the input buffer * for SSLv3 */ s->rstate = SSL_ST_READ_HEADER; s->packet_length = n; if (s->s3->rbuf.buf == NULL) if (!ssl3_setup_read_buffer(s)) goto err; s->packet = &(s->s3->rbuf.buf[0]); memcpy(s->packet, buf, n); s->s3->rbuf.left = n; s->s3->rbuf.offset = 0; } else { s->packet_length = 0; s->s3->rbuf.left = 0; s->s3->rbuf.offset = 0; } if (s->version == TLS1_2_VERSION) s->method = TLSv1_2_server_method(); else if (s->version == TLS1_1_VERSION) s->method = TLSv1_1_server_method(); else if (s->version == TLS1_VERSION) s->method = TLSv1_server_method(); else s->method = SSLv3_server_method(); #if 0 /* ssl3_get_client_hello does this */ s->client_version = (v[0]<<8)|v[1]; #endif s->handshake_func = s->method->ssl_accept; } if ((type < 1) || (type > 3)) { /* bad, very bad */ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); goto err; } s->init_num = 0; if (buf != buf_space) OPENSSL_free(buf); return (SSL_accept(s)); err: if (buf != buf_space) OPENSSL_free(buf); return (-1); }
THREAD_RETURN CYASSL_THREAD server_test(void* args) { SOCKET_T sockfd = 0; int clientfd = 0; SSL_METHOD* method = 0; SSL_CTX* ctx = 0; SSL* ssl = 0; char msg[] = "I hear you fa shizzle!"; char input[1024]; int idx; int ch; int version = SERVER_DEFAULT_VERSION; int doCliCertCheck = 1; int useAnyAddr = 0; int port = yasslPort; int usePsk = 0; int doDTLS = 0; int useNtruKey = 0; char* cipherList = NULL; char* verifyCert = (char*)cliCert; char* ourCert = (char*)svrCert; char* ourKey = (char*)svrKey; int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; ((func_args*)args)->return_code = -1; /* error state */ while ((ch = mygetopt(argc, argv, "?dbsnup:v:l:A:c:k:")) != -1) { switch (ch) { case '?' : Usage(); exit(EXIT_SUCCESS); case 'd' : doCliCertCheck = 0; break; case 'b' : useAnyAddr = 1; break; case 's' : usePsk = 1; break; case 'n' : useNtruKey = 1; break; case 'u' : doDTLS = 1; version = -1; /* DTLS flag */ break; case 'p' : port = atoi(myoptarg); break; case 'v' : version = atoi(myoptarg); if (version < 0 || version > 3) { Usage(); exit(MY_EX_USAGE); } if (doDTLS) version = -1; /* stay with DTLS */ break; case 'l' : cipherList = myoptarg; break; case 'A' : verifyCert = myoptarg; break; case 'c' : ourCert = myoptarg; break; case 'k' : ourKey = myoptarg; break; default: Usage(); exit(MY_EX_USAGE); } } argc -= myoptind; argv += myoptind; myoptind = 0; /* reset for test cases */ switch (version) { case 0: method = SSLv3_server_method(); break; case 1: method = TLSv1_server_method(); break; case 2: method = TLSv1_1_server_method(); break; case 3: method = TLSv1_2_server_method(); break; #ifdef CYASSL_DTLS case -1: method = DTLSv1_server_method(); break; #endif default: err_sys("Bad SSL version"); } if (method == NULL) err_sys("unable to get method"); ctx = SSL_CTX_new(method); if (ctx == NULL) err_sys("unable to get ctx"); if (cipherList) if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) err_sys("can't set cipher list"); if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" " CyaSSL home dir"); #ifdef HAVE_NTRU if (useNtruKey) { if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey) != SSL_SUCCESS) err_sys("can't load ntru key file, " "Please run from CyaSSL home dir"); } #endif if (!useNtruKey) { if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" " CyaSSL home dir"); } #ifndef NO_PSK if (usePsk) { SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb); SSL_CTX_use_psk_identity_hint(ctx, "cyassl server"); if (cipherList == NULL) if (SSL_CTX_set_cipher_list(ctx,"PSK-AES256-CBC-SHA") !=SSL_SUCCESS) err_sys("can't set cipher list"); } #endif /* if not using PSK, verify peer with certs */ if (doCliCertCheck && usePsk == 0) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0); if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from CyaSSL home dir"); } #ifdef OPENSSL_EXTRA SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC) /* don't use EDH, can't sniff tmp keys */ if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS) err_sys("can't set cipher list"); #endif ssl = SSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL"); #ifdef HAVE_CRL CyaSSL_EnableCRL(ssl, 0); CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON); CyaSSL_SetCRL_Cb(ssl, CRL_CallBack); #endif tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS); if (!doDTLS) CloseSocket(sockfd); SSL_set_fd(ssl, clientfd); #ifdef NO_PSK #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); #else SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */ #endif #endif #ifdef NON_BLOCKING tcp_set_nonblocking(&clientfd); NonBlockingSSL_Accept(ssl); #else #ifndef CYASSL_CALLBACKS if (SSL_accept(ssl) != SSL_SUCCESS) { int err = SSL_get_error(ssl, 0); char buffer[80]; printf("error = %d, %s\n", err, ERR_error_string(err, buffer)); err_sys("SSL_accept failed"); } #else NonBlockingSSL_Accept(ssl); #endif #endif showPeer(ssl); idx = SSL_read(ssl, input, sizeof(input)); if (idx > 0) { input[idx] = 0; printf("Client message: %s\n", input); } if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) err_sys("SSL_write failed"); SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); CloseSocket(clientfd); ((func_args*)args)->return_code = 0; return 0; }
eventer_ssl_ctx_t * eventer_ssl_ctx_new(eventer_ssl_orientation_t type, const char *layer, const char *certificate, const char *key, const char *ca, const char *ciphers) { char ssl_ctx_key[SSL_CTX_KEYLEN]; eventer_ssl_ctx_t *ctx; const char *layer_str; char *ctx_layer, *opts; char *opts_fallback = DEFAULT_OPTS_STRING; time_t now; ctx = calloc(1, sizeof(*ctx)); if(!ctx) return NULL; layer_str = layer ? layer : DEFAULT_LAYER_STRING; ctx_layer = alloca(strlen(layer_str)+1); memcpy(ctx_layer, layer_str, strlen(layer_str)+1); opts = strchr(ctx_layer,':'); if(opts) *opts++ = '\0'; else { opts = alloca(strlen(opts_fallback)+1); memcpy(opts, opts_fallback, strlen(opts_fallback)+1); } now = time(NULL); ssl_ctx_key_write(ssl_ctx_key, sizeof(ssl_ctx_key), type, layer, certificate, key, ca, ciphers); ctx->ssl_ctx_cn = ssl_ctx_cache_get(ssl_ctx_key); if(ctx->ssl_ctx_cn) { if(now - ctx->ssl_ctx_cn->creation_time > ssl_ctx_cache_expiry || (now - ctx->ssl_ctx_cn->last_stat_time > ssl_ctx_cache_finfo_expiry && (validate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate) || validate_finfo(&ctx->ssl_ctx_cn->key_finfo, key) || validate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca) || (ctx->ssl_ctx_cn->last_stat_time = now) == 0))) { /* assignment */ ssl_ctx_cache_remove(ssl_ctx_key); ssl_ctx_cache_node_free(ctx->ssl_ctx_cn); ctx->ssl_ctx_cn = NULL; } } if(!ctx->ssl_ctx_cn) { char *part = NULL, *brkt = NULL; long ctx_options = 0; ssl_ctx_cache_node *existing_ctx_cn; ctx->ssl_ctx_cn = calloc(1, sizeof(*ctx->ssl_ctx_cn)); ctx->ssl_ctx_cn->key = strdup(ssl_ctx_key); ctx->ssl_ctx_cn->refcnt = 1; ctx->ssl_ctx_cn->creation_time = now; ctx->ssl_ctx_cn->last_stat_time = now; populate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate); populate_finfo(&ctx->ssl_ctx_cn->key_finfo, key); populate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca); ctx->ssl_ctx = NULL; if(0) ; #if defined(SSL_TXT_SSLV3) && defined(HAVE_SSLV3_SERVER) && defined(HAVE_SSLV3_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_SSLV3)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv3_server_method() : SSLv3_client_method()); #endif #if defined(SSL_TXT_SSLV2) && defined(HAVE_SSLV2_SERVER) && defined(HAVE_SSLV2_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_SSLV2)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv2_server_method() : SSLv2_client_method()); #endif #if defined(SSL_TXT_TLSV1) && defined(HAVE_TLSV1_SERVER) && defined(HAVE_TLSV1_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_server_method() : TLSv1_client_method()); #endif #if defined(SSL_TXT_TLSV1_1) && defined(HAVE_TLSV1_1_SERVER) && defined(HAVE_TLSV1_1_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_1)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_1_server_method() : TLSv1_1_client_method()); #endif #if defined(SSL_TXT_TLSV1_2) && defined(HAVE_TLSV1_2_SERVER) && defined(HAVE_TLSV1_2_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_2)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_2_server_method() : TLSv1_2_client_method()); #endif if(ctx->ssl_ctx == NULL) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv23_server_method() : SSLv23_client_method()); if(!ctx->ssl_ctx) goto bail; for(part = strtok_r(opts, ",", &brkt); part; part = strtok_r(NULL, ",", &brkt)) { char *optname = part; int neg = 0; if(*optname == '!') neg = 1, optname++; #define SETBITOPT(name, neg, opt) \ if(!strcasecmp(optname, name)) { \ if(neg) ctx_options &= ~(opt); \ else ctx_options |= (opt); \ } SETBITOPT("all", neg, SSL_OP_ALL) #ifdef SSL_TXT_SSLV2 else SETBITOPT(SSL_TXT_SSLV2, !neg, SSL_OP_NO_SSLv2) #endif #ifdef SSL_TXT_SSLV3 else SETBITOPT(SSL_TXT_SSLV3, !neg, SSL_OP_NO_SSLv3) #endif #ifdef SSL_TXT_TLSV1 else SETBITOPT(SSL_TXT_TLSV1, !neg, SSL_OP_NO_TLSv1) #endif #ifdef SSL_TXT_TLSV1_1 else SETBITOPT(SSL_TXT_TLSV1_1, !neg, SSL_OP_NO_TLSv1_1) #endif #ifdef SSL_TXT_TLSV1_2 else SETBITOPT(SSL_TXT_TLSV1_2, !neg, SSL_OP_NO_TLSv1_2) #endif #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE else SETBITOPT("cipher_server_preference", neg, SSL_OP_CIPHER_SERVER_PREFERENCE) #endif else { mtevL(mtev_error, "SSL layer part '%s' not understood.\n", optname); } } if (type == SSL_SERVER) SSL_CTX_set_session_id_context(ctx->ssl_ctx, (unsigned char *)EVENTER_SSL_DATANAME, sizeof(EVENTER_SSL_DATANAME)-1); #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #endif #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; #endif #ifdef SSL_OP_NO_COMPRESSION ctx_options |= SSL_OP_NO_COMPRESSION; #endif #ifdef SSL_OP_NO_TICKET ctx_options |= SSL_OP_NO_TICKET; #endif #ifdef SSL_OP_SINGLE_DH_USE ctx_options |= SSL_OP_SINGLE_DH_USE; #endif #ifdef SSL_OP_SINGLE_ECDH_USE ctx_options |= SSL_OP_SINGLE_ECDH_USE; #endif SSL_CTX_set_options(ctx->ssl_ctx, ctx_options); #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); #endif if(certificate && SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1) goto bail; if(key && SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key, SSL_FILETYPE_PEM) != 1) goto bail; if(ca) { STACK_OF(X509_NAME) *cert_stack; if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) || (cert_stack = SSL_load_client_CA_file(ca)) == NULL) goto bail; SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack); } SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT"); SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_cb); #ifndef OPENSSL_NO_EC #if defined(SSL_CTX_set_ecdh_auto) SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1); #elif defined(NID_X9_62_prime256v1) EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); SSL_CTX_set_tmp_ecdh(ctx->ssl_ctx, ec_key); EC_KEY_free(ec_key); #endif #endif existing_ctx_cn = ssl_ctx_cache_set(ctx->ssl_ctx_cn); if(existing_ctx_cn != ctx->ssl_ctx_cn) { ssl_ctx_cache_node_free(ctx->ssl_ctx_cn); ctx->ssl_ctx_cn = existing_ctx_cn; } }
/* -------------------------------------------------------------------- */ SSL_CTX* evssl_init(const echossl_t *options, int isserver) { /*-*/ SSL_CTX *context = NULL; /*-*/ char *crtfile = NULL; /*-*/ char *keyfile = NULL; /*-*/ char *dhfile = NULL; /*-*/ char *CApath = NULL; const SSL_METHOD *method = NULL; if (options->sname != NULL) { crtfile = xjoin(options->pki, "/certificates/", options->sname, ".crt", NULL); keyfile = xjoin(options->pki, "/certificates/", options->sname, ".key", NULL); } dhfile = xjoin(options->pki, "/certificates/dh.pem", NULL); CApath = xjoin(options->pki, "/db/ca.db.certs", NULL); SSL_load_error_strings(); SSL_library_init(); if (!RAND_poll()) { elog(LOG_FATAL, "cannot initialize entropy"); goto bailout; } if (isserver) { switch (options->tlsver) { case SSL_3p0: method = SSLv3_server_method (); break ; case TLS_1p0: method = TLSv1_server_method (); break ; case TLS_1p1: method = TLSv1_1_server_method(); break ; case TLS_1p2: method = TLSv1_2_server_method(); break ; default: abort(); } } else { switch (options->tlsver) { case SSL_3p0: method = SSLv3_client_method (); break ; case TLS_1p0: method = TLSv1_client_method (); break ; case TLS_1p1: method = TLSv1_1_client_method(); break ; case TLS_1p2: method = TLSv1_2_client_method(); break ; default: abort(); } } if ((context = SSL_CTX_new(method)) == NULL) { elog(LOG_FATAL, "cannot create SSL context"); goto bailout; } if (options->ciphers != NULL) { if (!SSL_CTX_set_cipher_list(context, options->ciphers)) { elog(LOG_FATAL, "cannot set ciphers list `%s'", options->ciphers); goto bailout; } } if (!SSL_CTX_use_tmp_dh_file(context, dhfile)) { elog(LOG_FATAL, "cannot load/set DH parameters from file `%s'", dhfile); goto bailout; } if (!SSL_CTX_load_verify_locations(context, NULL, CApath)) { elog(LOG_FATAL, "cannot load trusted hashed CA path"); goto bailout; } (void) SSL_CTX_set_default_verify_paths(context); if (isserver) { if (options->sname != NULL) { if (!SSL_CTX_use_certificate_chain_file(context, crtfile)) { elog(LOG_FATAL, "cannot load certificate `%s'", crtfile); goto bailout; } if (!SSL_CTX_use_PrivateKey_file(context, keyfile, SSL_FILETYPE_PEM)) { elog(LOG_FATAL, "cannot load certificate key `%s'", keyfile); goto bailout; } } } (void) SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION); if (options->sname != NULL) { free(keyfile); free(crtfile); } free(dhfile); free(CApath); return context; bailout: if (context != NULL) SSL_CTX_free(context); if (keyfile != NULL) free(keyfile); if (crtfile != NULL) free(crtfile); if (dhfile != NULL) free(dhfile); if (CApath != NULL) free(CApath); return NULL; }
THREAD_RETURN CYASSL_THREAD server_test(void* args) { SOCKET_T sockfd = 0; SOCKET_T clientfd = 0; SSL_METHOD* method = 0; SSL_CTX* ctx = 0; SSL* ssl = 0; char msg[] = "I hear you fa shizzle!"; char input[80]; int idx; int ch; int version = SERVER_DEFAULT_VERSION; int doCliCertCheck = 1; int useAnyAddr = 0; word16 port = yasslPort; int usePsk = 0; int useAnon = 0; int doDTLS = 0; int useNtruKey = 0; int nonBlocking = 0; int trackMemory = 0; int fewerPackets = 0; int pkCallbacks = 0; int serverReadyFile = 0; char* cipherList = NULL; const char* verifyCert = cliCert; const char* ourCert = svrCert; const char* ourKey = svrKey; int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; #ifdef HAVE_SNI char* sniHostName = NULL; #endif #ifdef HAVE_OCSP int useOcsp = 0; char* ocspUrl = NULL; #endif ((func_args*)args)->return_code = -1; /* error state */ #ifdef NO_RSA verifyCert = (char*)cliEccCert; ourCert = (char*)eccCert; ourKey = (char*)eccKey; #endif (void)trackMemory; (void)pkCallbacks; #ifdef CYASSL_TIRTOS fdOpenSession(Task_self()); #endif while ((ch = mygetopt(argc, argv, "?dbstnNufraPp:v:l:A:c:k:S:oO:")) != -1) { switch (ch) { case '?' : Usage(); exit(EXIT_SUCCESS); case 'd' : doCliCertCheck = 0; break; case 'b' : useAnyAddr = 1; break; case 's' : usePsk = 1; break; case 't' : #ifdef USE_CYASSL_MEMORY trackMemory = 1; #endif break; case 'n' : useNtruKey = 1; break; case 'u' : doDTLS = 1; break; case 'f' : fewerPackets = 1; break; case 'r' : serverReadyFile = 1; break; case 'P' : #ifdef HAVE_PK_CALLBACKS pkCallbacks = 1; #endif break; case 'p' : port = (word16)atoi(myoptarg); #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API) if (port == 0) err_sys("port number cannot be 0"); #endif break; case 'v' : version = atoi(myoptarg); if (version < 0 || version > 3) { Usage(); exit(MY_EX_USAGE); } break; case 'l' : cipherList = myoptarg; break; case 'A' : verifyCert = myoptarg; break; case 'c' : ourCert = myoptarg; break; case 'k' : ourKey = myoptarg; break; case 'N': nonBlocking = 1; break; case 'S' : #ifdef HAVE_SNI sniHostName = myoptarg; #endif break; case 'o' : #ifdef HAVE_OCSP useOcsp = 1; #endif break; case 'O' : #ifdef HAVE_OCSP useOcsp = 1; ocspUrl = myoptarg; #endif break; case 'a' : #ifdef HAVE_ANON useAnon = 1; #endif break; default: Usage(); exit(MY_EX_USAGE); } } myoptind = 0; /* reset for test cases */ /* sort out DTLS versus TLS versions */ if (version == CLIENT_INVALID_VERSION) { if (doDTLS) version = CLIENT_DTLS_DEFAULT_VERSION; else version = CLIENT_DEFAULT_VERSION; } else { if (doDTLS) { if (version == 3) version = -2; else version = -1; } } #ifdef USE_CYASSL_MEMORY if (trackMemory) InitMemoryTracker(); #endif switch (version) { #ifndef NO_OLD_TLS case 0: method = SSLv3_server_method(); break; #ifndef NO_TLS case 1: method = TLSv1_server_method(); break; case 2: method = TLSv1_1_server_method(); break; #endif #endif #ifndef NO_TLS case 3: method = TLSv1_2_server_method(); break; #endif #ifdef CYASSL_DTLS case -1: method = DTLSv1_server_method(); break; case -2: method = DTLSv1_2_server_method(); break; #endif default: err_sys("Bad SSL version"); } if (method == NULL) err_sys("unable to get method"); ctx = SSL_CTX_new(method); if (ctx == NULL) err_sys("unable to get ctx"); if (cipherList) if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) err_sys("server can't set cipher list 1"); #ifdef CYASSL_LEANPSK usePsk = 1; #endif #if defined(NO_RSA) && !defined(HAVE_ECC) usePsk = 1; #endif if (fewerPackets) CyaSSL_CTX_set_group_messages(ctx); #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) if (!usePsk && !useAnon) { if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" " CyaSSL home dir"); } #endif #ifdef HAVE_NTRU if (useNtruKey) { if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey) != SSL_SUCCESS) err_sys("can't load ntru key file, " "Please run from CyaSSL home dir"); } #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) if (!useNtruKey && !usePsk && !useAnon) { if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server private key file, check file and run " "from CyaSSL home dir"); } #endif if (usePsk) { #ifndef NO_PSK SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb); SSL_CTX_use_psk_identity_hint(ctx, "cyassl server"); if (cipherList == NULL) { const char *defaultCipherList; #ifdef HAVE_NULL_CIPHER defaultCipherList = "PSK-NULL-SHA256"; #else defaultCipherList = "PSK-AES128-CBC-SHA256"; #endif if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS) err_sys("server can't set cipher list 2"); } #endif } if (useAnon) { #ifdef HAVE_ANON CyaSSL_CTX_allow_anon_cipher(ctx); if (cipherList == NULL) { if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS) err_sys("server can't set cipher list 4"); } #endif } #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) /* if not using PSK, verify peer with certs */ if (doCliCertCheck && usePsk == 0 && useAnon == 0) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0); if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from CyaSSL home dir"); } #endif #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC) /* don't use EDH, can't sniff tmp keys */ if (cipherList == NULL) { if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS) err_sys("server can't set cipher list 3"); } #endif #ifdef HAVE_SNI if (sniHostName) if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName, XSTRLEN(sniHostName)) != SSL_SUCCESS) err_sys("UseSNI failed"); #endif ssl = SSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL"); #ifdef HAVE_CRL CyaSSL_EnableCRL(ssl, 0); CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON); CyaSSL_SetCRL_Cb(ssl, CRL_CallBack); #endif #ifdef HAVE_OCSP if (useOcsp) { if (ocspUrl != NULL) { CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl); CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE | CYASSL_OCSP_URL_OVERRIDE); } else CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE); } #endif #ifdef HAVE_PK_CALLBACKS if (pkCallbacks) SetupPkCallbacks(ctx, ssl); #endif tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS, serverReadyFile); if (!doDTLS) CloseSocket(sockfd); SSL_set_fd(ssl, clientfd); if (usePsk == 0 || useAnon == 1 || cipherList != NULL) { #if !defined(NO_FILESYSTEM) && !defined(NO_DH) CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); #elif !defined(NO_DH) SetDH(ssl); /* repick suites with DHE, higher priority than PSK */ #endif } #ifndef CYASSL_CALLBACKS if (nonBlocking) { CyaSSL_set_using_nonblock(ssl, 1); tcp_set_nonblocking(&clientfd); NonBlockingSSL_Accept(ssl); } else if (SSL_accept(ssl) != SSL_SUCCESS) { int err = SSL_get_error(ssl, 0); char buffer[CYASSL_MAX_ERROR_SZ]; printf("error = %d, %s\n", err, ERR_error_string(err, buffer)); err_sys("SSL_accept failed"); } #else NonBlockingSSL_Accept(ssl); #endif showPeer(ssl); idx = SSL_read(ssl, input, sizeof(input)-1); if (idx > 0) { input[idx] = 0; printf("Client message: %s\n", input); } else if (idx < 0) { int readErr = SSL_get_error(ssl, 0); if (readErr != SSL_ERROR_WANT_READ) err_sys("SSL_read failed"); } if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) err_sys("SSL_write failed"); #if defined(CYASSL_MDK_SHELL) && defined(HAVE_MDK_RTX) os_dly_wait(500) ; #elif defined (CYASSL_TIRTOS) Task_yield(); #endif SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); CloseSocket(clientfd); ((func_args*)args)->return_code = 0; #if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \ && defined(HAVE_THREAD_LS) ecc_fp_free(); /* free per thread cache */ #endif #ifdef USE_CYASSL_MEMORY if (trackMemory) ShowMemoryTracker(); #endif #ifdef CYASSL_TIRTOS fdCloseSession(Task_self()); #endif #ifndef CYASSL_TIRTOS return 0; #endif }
THREAD_RETURN CYASSL_THREAD server_test(void* args) { SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID; SSL_METHOD* method = 0; SSL_CTX* ctx = 0; SSL* ssl = 0; const char msg[] = "I hear you fa shizzle!"; char input[80]; int ch; int version = SERVER_DEFAULT_VERSION; int doCliCertCheck = 1; int useAnyAddr = 0; word16 port = wolfSSLPort; int usePsk = 0; int usePskPlus = 0; int useAnon = 0; int doDTLS = 0; int needDH = 0; int useNtruKey = 0; int nonBlocking = 0; int trackMemory = 0; int fewerPackets = 0; int pkCallbacks = 0; int wc_shutdown = 0; int resume = 0; int resumeCount = 0; int loopIndefinitely = 0; int echoData = 0; int throughput = 0; int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS; short minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS; short minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS; int doListen = 1; int crlFlags = 0; int ret; int err = 0; char* serverReadyFile = NULL; char* alpnList = NULL; unsigned char alpn_opt = 0; char* cipherList = NULL; const char* verifyCert = cliCert; const char* ourCert = svrCert; const char* ourKey = svrKey; const char* ourDhParam = dhParam; tcp_ready* readySignal = NULL; int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; #ifdef WOLFSSL_TRUST_PEER_CERT const char* trustCert = NULL; #endif #ifndef NO_PSK int sendPskIdentityHint = 1; #endif #ifdef HAVE_SNI char* sniHostName = NULL; #endif #ifdef HAVE_OCSP int useOcsp = 0; char* ocspUrl = NULL; #endif ((func_args*)args)->return_code = -1; /* error state */ #ifdef NO_RSA verifyCert = (char*)cliEccCert; ourCert = (char*)eccCert; ourKey = (char*)eccKey; #endif (void)trackMemory; (void)pkCallbacks; (void)needDH; (void)ourKey; (void)ourCert; (void)ourDhParam; (void)verifyCert; (void)useNtruKey; (void)doCliCertCheck; (void)minDhKeyBits; (void)minRsaKeyBits; (void)minEccKeyBits; (void)alpnList; (void)alpn_opt; (void)crlFlags; (void)readySignal; #ifdef CYASSL_TIRTOS fdOpenSession(Task_self()); #endif #ifdef WOLFSSL_VXWORKS useAnyAddr = 1; #else while ((ch = mygetopt(argc, argv, "?jdbstnNufrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:")) != -1) { switch (ch) { case '?' : Usage(); exit(EXIT_SUCCESS); case 'd' : doCliCertCheck = 0; break; case 'b' : useAnyAddr = 1; break; case 's' : usePsk = 1; break; case 'j' : usePskPlus = 1; break; case 't' : #ifdef USE_WOLFSSL_MEMORY trackMemory = 1; #endif break; case 'n' : useNtruKey = 1; break; case 'u' : doDTLS = 1; break; case 'f' : fewerPackets = 1; break; case 'R' : serverReadyFile = myoptarg; break; case 'r' : #ifndef NO_SESSION_CACHE resume = 1; #endif break; case 'P' : #ifdef HAVE_PK_CALLBACKS pkCallbacks = 1; #endif break; case 'p' : port = (word16)atoi(myoptarg); break; case 'w' : wc_shutdown = 1; break; case 'v' : version = atoi(myoptarg); if (version < 0 || version > 3) { Usage(); exit(MY_EX_USAGE); } break; case 'l' : cipherList = myoptarg; break; case 'A' : verifyCert = myoptarg; break; case 'c' : ourCert = myoptarg; break; case 'k' : ourKey = myoptarg; break; case 'D' : #ifndef NO_DH ourDhParam = myoptarg; #endif break; case 'Z' : #ifndef NO_DH minDhKeyBits = atoi(myoptarg); if (minDhKeyBits <= 0 || minDhKeyBits > 16000) { Usage(); exit(MY_EX_USAGE); } #endif break; case 'N': nonBlocking = 1; break; case 'S' : #ifdef HAVE_SNI sniHostName = myoptarg; #endif break; case 'o' : #ifdef HAVE_OCSP useOcsp = 1; #endif break; case 'O' : #ifdef HAVE_OCSP useOcsp = 1; ocspUrl = myoptarg; #endif break; case 'a' : #ifdef HAVE_ANON useAnon = 1; #endif break; case 'I': #ifndef NO_PSK sendPskIdentityHint = 0; #endif break; case 'L' : #ifdef HAVE_ALPN alpnList = myoptarg; if (alpnList[0] == 'C' && alpnList[1] == ':') alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH; else if (alpnList[0] == 'F' && alpnList[1] == ':') alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH; else { Usage(); exit(MY_EX_USAGE); } alpnList += 2; #endif break; case 'i' : loopIndefinitely = 1; break; case 'e' : echoData = 1; break; case 'B': throughput = atoi(myoptarg); if (throughput <= 0) { Usage(); exit(MY_EX_USAGE); } break; #ifdef WOLFSSL_TRUST_PEER_CERT case 'E' : trustCert = myoptarg; break; #endif default: Usage(); exit(MY_EX_USAGE); } } myoptind = 0; /* reset for test cases */ #endif /* !WOLFSSL_VXWORKS */ /* sort out DTLS versus TLS versions */ if (version == CLIENT_INVALID_VERSION) { if (doDTLS) version = CLIENT_DTLS_DEFAULT_VERSION; else version = CLIENT_DEFAULT_VERSION; } else { if (doDTLS) { if (version == 3) version = -2; else version = -1; } } #ifdef USE_CYASSL_MEMORY if (trackMemory) InitMemoryTracker(); #endif switch (version) { #ifndef NO_OLD_TLS #ifdef WOLFSSL_ALLOW_SSLV3 case 0: method = SSLv3_server_method(); break; #endif #ifndef NO_TLS case 1: method = TLSv1_server_method(); break; case 2: method = TLSv1_1_server_method(); break; #endif #endif #ifndef NO_TLS case 3: method = TLSv1_2_server_method(); break; #endif #ifdef CYASSL_DTLS #ifndef NO_OLD_TLS case -1: method = DTLSv1_server_method(); break; #endif case -2: method = DTLSv1_2_server_method(); break; #endif default: err_sys("Bad SSL version"); } if (method == NULL) err_sys("unable to get method"); ctx = SSL_CTX_new(method); if (ctx == NULL) err_sys("unable to get ctx"); #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \ defined(HAVE_POLY1305) if (TicketInit() != 0) err_sys("unable to setup Session Ticket Key context"); wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb); #endif if (cipherList) if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) err_sys("server can't set cipher list 1"); #ifdef CYASSL_LEANPSK if (!usePsk) { usePsk = 1; } #endif #if defined(NO_RSA) && !defined(HAVE_ECC) if (!usePsk) { usePsk = 1; } #endif if (fewerPackets) CyaSSL_CTX_set_group_messages(ctx); #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) if ((!usePsk || usePskPlus) && !useAnon) { if (SSL_CTX_use_certificate_chain_file(ctx, ourCert) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" " wolfSSL home dir"); } #endif #ifndef NO_DH if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits) != SSL_SUCCESS) { err_sys("Error setting minimum DH key size"); } #endif #ifndef NO_RSA if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != SSL_SUCCESS){ err_sys("Error setting minimum RSA key size"); } #endif #ifdef HAVE_ECC if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != SSL_SUCCESS){ err_sys("Error setting minimum ECC key size"); } #endif #ifdef HAVE_NTRU if (useNtruKey) { if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey) != SSL_SUCCESS) err_sys("can't load ntru key file, " "Please run from wolfSSL home dir"); } #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon) { if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server private key file, check file and run " "from wolfSSL home dir"); } #endif if (usePsk || usePskPlus) { #ifndef NO_PSK SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb); if (sendPskIdentityHint == 1) SSL_CTX_use_psk_identity_hint(ctx, "cyassl server"); if (cipherList == NULL && !usePskPlus) { const char *defaultCipherList; #if defined(HAVE_AESGCM) && !defined(NO_DH) defaultCipherList = "DHE-PSK-AES128-GCM-SHA256"; needDH = 1; #elif defined(HAVE_NULL_CIPHER) defaultCipherList = "PSK-NULL-SHA256"; #else defaultCipherList = "PSK-AES128-CBC-SHA256"; #endif if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS) err_sys("server can't set cipher list 2"); } #endif } if (useAnon) { #ifdef HAVE_ANON CyaSSL_CTX_allow_anon_cipher(ctx); if (cipherList == NULL) { if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS) err_sys("server can't set cipher list 4"); } #endif } #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) /* if not using PSK, verify peer with certs if using PSK Plus then verify peer certs except PSK suites */ if (doCliCertCheck && (usePsk == 0 || usePskPlus) && useAnon == 0) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | ((usePskPlus)? SSL_VERIFY_FAIL_EXCEPT_PSK : SSL_VERIFY_FAIL_IF_NO_PEER_CERT),0); if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); #ifdef WOLFSSL_TRUST_PEER_CERT if (trustCert) { if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert, SSL_FILETYPE_PEM)) != SSL_SUCCESS) { err_sys("can't load trusted peer cert file"); } } #endif /* WOLFSSL_TRUST_PEER_CERT */ } #endif #if defined(CYASSL_SNIFFER) /* don't use EDH, can't sniff tmp keys */ if (cipherList == NULL) { if (SSL_CTX_set_cipher_list(ctx, "AES128-SHA") != SSL_SUCCESS) err_sys("server can't set cipher list 3"); } #endif #ifdef HAVE_SNI if (sniHostName) if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName, XSTRLEN(sniHostName)) != SSL_SUCCESS) err_sys("UseSNI failed"); #endif #ifdef USE_WINDOWS_API if (port == 0) { /* Generate random port for testing */ port = GetRandomPort(); } #endif /* USE_WINDOWS_API */ while (1) { /* allow resume option */ if(resumeCount > 1) { if (doDTLS == 0) { SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); clientfd = accept(sockfd, (struct sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); } else { tcp_listen(&sockfd, &port, useAnyAddr, doDTLS); clientfd = sockfd; } if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) { err_sys("tcp accept failed"); } } ssl = SSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL"); #ifndef NO_HANDSHAKE_DONE_CB wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL); #endif #ifdef HAVE_CRL #ifdef HAVE_CRL_MONITOR crlFlags = CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON; #endif if (CyaSSL_EnableCRL(ssl, 0) != SSL_SUCCESS) err_sys("unable to enable CRL"); if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, crlFlags) != SSL_SUCCESS) err_sys("unable to load CRL"); if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS) err_sys("unable to set CRL callback url"); #endif #ifdef HAVE_OCSP if (useOcsp) { if (ocspUrl != NULL) { CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl); CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE | CYASSL_OCSP_URL_OVERRIDE); } else CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE); } #endif #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS) err_sys("can't enable OCSP Stapling Certificate Manager"); if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate1-ca-cert.pem", 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate2-ca-cert.pem", 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate3-ca-cert.pem", 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); #endif #ifdef HAVE_PK_CALLBACKS if (pkCallbacks) SetupPkCallbacks(ctx, ssl); #endif /* do accept */ readySignal = ((func_args*)args)->signal; if (readySignal) { readySignal->srfName = serverReadyFile; } tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS, serverReadyFile ? 1 : 0, doListen); doListen = 0; /* Don't listen next time */ if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) { err_sys("error in setting fd"); } #ifdef HAVE_ALPN if (alpnList != NULL) { printf("ALPN accepted protocols list : %s\n", alpnList); wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt); } #endif #ifdef WOLFSSL_DTLS if (doDTLS) { SOCKADDR_IN_T cliaddr; byte b[1500]; int n; socklen_t len = sizeof(cliaddr); /* For DTLS, peek at the next datagram so we can get the client's * address and set it into the ssl object later to generate the * cookie. */ n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK, (struct sockaddr*)&cliaddr, &len); if (n <= 0) err_sys("recvfrom failed"); wolfSSL_dtls_set_peer(ssl, &cliaddr, len); } #endif if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL || needDH == 1) { #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN) CyaSSL_SetTmpDH_file(ssl, ourDhParam, SSL_FILETYPE_PEM); #elif !defined(NO_DH) SetDH(ssl); /* repick suites with DHE, higher priority than PSK */ #endif } #ifndef CYASSL_CALLBACKS if (nonBlocking) { CyaSSL_set_using_nonblock(ssl, 1); tcp_set_nonblocking(&clientfd); } #endif do { #ifdef WOLFSSL_ASYNC_CRYPT if (err == WC_PENDING_E) { ret = AsyncCryptPoll(ssl); if (ret < 0) { break; } else if (ret == 0) { continue; } } #endif err = 0; /* Reset error */ #ifndef CYASSL_CALLBACKS if (nonBlocking) { ret = NonBlockingSSL_Accept(ssl); } else { ret = SSL_accept(ssl); } #else ret = NonBlockingSSL_Accept(ssl); #endif if (ret != SSL_SUCCESS) { err = SSL_get_error(ssl, 0); } } while (ret != SSL_SUCCESS && err == WC_PENDING_E); if (ret != SSL_SUCCESS) { char buffer[CYASSL_MAX_ERROR_SZ]; err = SSL_get_error(ssl, 0); printf("error = %d, %s\n", err, ERR_error_string(err, buffer)); err_sys("SSL_accept failed"); } showPeer(ssl); #ifdef HAVE_ALPN if (alpnList != NULL) { char *protocol_name = NULL, *list = NULL; word16 protocol_nameSz = 0, listSz = 0; err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz); if (err == SSL_SUCCESS) printf("Sent ALPN protocol : %s (%d)\n", protocol_name, protocol_nameSz); else if (err == SSL_ALPN_NOT_FOUND) printf("No ALPN response sent (no match)\n"); else printf("Getting ALPN protocol name failed\n"); err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz); if (err == SSL_SUCCESS) printf("List of protocol names sent by Client: %s (%d)\n", list, listSz); else printf("Get list of client's protocol name failed\n"); free(list); } #endif if(echoData == 0 && throughput == 0) { ret = SSL_read(ssl, input, sizeof(input)-1); if (ret > 0) { input[ret] = 0; printf("Client message: %s\n", input); } else if (ret < 0) { int readErr = SSL_get_error(ssl, 0); if (readErr != SSL_ERROR_WANT_READ) err_sys("SSL_read failed"); } if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) err_sys("SSL_write failed"); } else { ServerEchoData(ssl, clientfd, echoData, throughput); } #if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX) os_dly_wait(500) ; #elif defined (CYASSL_TIRTOS) Task_yield(); #endif if (doDTLS == 0) { ret = SSL_shutdown(ssl); if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE) SSL_shutdown(ssl); /* bidirectional shutdown */ } SSL_free(ssl); CloseSocket(clientfd); if (resume == 1 && resumeCount == 0) { resumeCount++; /* only do one resume for testing */ continue; } resumeCount = 0; if(!loopIndefinitely) { break; /* out of while loop, done with normal and resume option */ } } /* while(1) */ CloseSocket(sockfd); SSL_CTX_free(ctx); ((func_args*)args)->return_code = 0; #if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \ && defined(HAVE_THREAD_LS) ecc_fp_free(); /* free per thread cache */ #endif #ifdef USE_WOLFSSL_MEMORY if (trackMemory) ShowMemoryTracker(); #endif #ifdef CYASSL_TIRTOS fdCloseSession(Task_self()); #endif #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \ defined(HAVE_POLY1305) TicketCleanup(); #endif /* There are use cases when these assignments are not read. To avoid * potential confusion those warnings have been handled here. */ (void) ourKey; (void) verifyCert; (void) doCliCertCheck; (void) useNtruKey; (void) ourDhParam; (void) ourCert; #ifndef CYASSL_TIRTOS return 0; #endif }
int anetSSLAccept( char *err, int fd, struct redisServer server, anetSSLConnection *ctn) { ctn->sd = -1; ctn->ctx = NULL; ctn->ssl = NULL; ctn->bio = NULL; ctn->conn_str = NULL; if( fd == -1 ) { return ANET_ERR; } ctn->sd = fd; // Create the SSL Context ( server method ) SSL_CTX* ctx = SSL_CTX_new(TLSv1_1_server_method()); ctn->ctx = ctx; /* You will need to generate certificates, the root certificate authority file, the private key file, and the random file yourself. Google will help. The openssl executable created when you compiled OpenSSL can do all this. */ // Load trusted root authorities SSL_CTX_load_verify_locations(ctx, server.ssl_root_file, server.ssl_root_dir); // Sets the default certificate password callback function. Read more under the Certificate Verification section. if( NULL != server.ssl_srvr_cert_passwd ) { global_ssl_cert_password = server.ssl_srvr_cert_passwd; SSL_CTX_set_default_passwd_cb(ctx, password_callback); } // Sets the certificate file to be used. SSL_CTX_use_certificate_file(ctx, server.ssl_cert_file, SSL_FILETYPE_PEM); // Sets the private key file to be used. SSL_CTX_use_PrivateKey_file(ctx, server.ssl_pk_file, SSL_FILETYPE_PEM); // Set the maximum depth to be used verifying certificates // Due to a bug, this is not enforced. The verify callback must enforce it. SSL_CTX_set_verify_depth(ctx, 1); // Set the certificate verification callback. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER /* | SSL_VERIFY_FAIL_IF_NO_PEER_CERT */, verify_callback); /* End certificate verification setup. */ // We need to load the Diffie-Hellman key exchange parameters. // First load dh1024.pem (you DID create it, didn't you?) BIO* bio = BIO_new_file(server.ssl_dhk_file, "r"); // Did we get a handle to the file? if (bio == NULL) { anetSetError(err, "SSL Accept: Couldn't open DH param file"); anetCleanupSSL( ctn); return ANET_ERR; } // Read in the DH params. DH* ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); // Free up the BIO object. BIO_free(bio); // Set up our SSL_CTX to use the DH parameters. if (SSL_CTX_set_tmp_dh(ctx, ret) < 0) { anetSetError(err, "SSL Accept: Couldn't set DH parameters"); anetCleanupSSL( ctn ); return ANET_ERR; } // Now we need to generate a RSA key for use. // 1024-bit key. If you want to use something stronger, go ahead but it must be a power of 2. Upper limit should be 4096. RSA* rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL); // Set up our SSL_CTX to use the generated RSA key. if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) { anetSetError(err, "SSL Accept: Couldn't set RSA Key"); anetCleanupSSL( ctn ); return ANET_ERR; } // Free up the RSA structure. RSA_free(rsa); /* For some reason many tutorials don't include this... Servers must specify the ciphers they can use, to verify that both the client and the server can use the same cipher. If you don't do this, you'll get errors relating to "no shared ciphers" or "no common ciphers". Use all ciphers with the exception of: ones with anonymous Diffie-Hellman, low-strength ciphers, export ciphers, md5 hashing. Ordered from strongest to weakest. Note that as ciphers become broken, it will be necessary to change the available cipher list to remain secure. */ if( NULL == server.ssl_srvr_cipher_list || 0 == strlen(server.ssl_srvr_cipher_list) ) SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); else SSL_CTX_set_cipher_list(ctx, server.ssl_srvr_cipher_list); // Set up our SSL object as before SSL* ssl = SSL_new(ctx); ctn->ssl = ssl; // Set up our BIO object to use the client socket BIO* sslclient = BIO_new_socket(fd, BIO_NOCLOSE); ctn->bio = sslclient; // Set up our SSL object to use the BIO. SSL_set_bio(ssl, sslclient, sslclient); // Do SSL handshaking. int r = SSL_accept(ssl); // Something failed. Print out all the error information, since all of it may be relevant to the problem. if (r != 1) { char error[65535]; ERR_error_string_n(ERR_get_error(), error, 65535); anetSetError(err, "SSL Accept: Error %d - %s ", SSL_get_error(ssl, r), error ); // We failed to accept this client connection. // Ideally here you'll drop the connection and continue on. anetCleanupSSL( ctn ); return ANET_ERR; } /* Verify certificate */ if (SSL_get_verify_result(ssl) != X509_V_OK) { anetSetError(err, "SSL Accept: Certificate failed verification!"); // Ideally here you'll close this connection and continue on. anetCleanupSSL( ctn ); return ANET_ERR; } return ANET_OK; }
/* caller == ssl client, !client == ssl server */ int ssl_init(int caller, int fd, int iscontrol) { const SSL_METHOD *method; int ret; SSL_CTX **curctx; SSL **curssl; if (!_use_ssl) return 0; SSL_library_init (); SSL_load_error_strings (); if (iscontrol) { curctx = &control_ctx; curssl = &control_ssl; } else { curctx = &ctx; curssl = &ssl; } #if 0 if (caller) // method = SSLv23_client_method(); method = TLSv1_1_client_method(); else //method = SSLv23_method(); method = TLSv1_1_server_method(); #endif method = SSLv23_method(); *curctx = SSL_CTX_new (method); if (*curctx == NULL) { ERR_print_errors_fp(stderr); return -1; } /* Load cert */ if(!(SSL_CTX_use_certificate_file(*curctx, certfile, SSL_FILETYPE_PEM))) { ERR_print_errors_fp(stderr); return -1; } /* Load private key */ if(!(SSL_CTX_use_PrivateKey_file(*curctx, keyfile, SSL_FILETYPE_PEM))) { ERR_print_errors_fp(stderr); return -1; } /* Load the CAs we trust*/ if(!(SSL_CTX_load_verify_locations(*curctx, cafile, 0))) { ERR_print_errors_fp(stderr); return -1; } /* if in server role request peer's cert */ //if (!caller) SSL_CTX_set_verify(*curctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_CLIENT_ONCE, 0); SSL_CTX_set_verify_depth(*curctx, 1); STACK_OF(X509_NAME) *cert_names; cert_names = SSL_load_client_CA_file(cafile); if (cert_names != NULL) { printf("loaded client ca list\n"); SSL_CTX_set_client_CA_list(*curctx, cert_names); } else printf("not loaded client ca list\n"); SSL_CTX_set_mode(*curctx, SSL_MODE_AUTO_RETRY); *curssl = SSL_new(*curctx); if (*curssl == NULL) { ERR_print_errors_fp(stderr); return -1; } if (!SSL_set_fd (*curssl, fd)) { ERR_print_errors_fp(stderr); return -1; } if (caller) { if (SSL_connect (*curssl) != 1) { ERR_print_errors_fp(stderr); printf("ssl error %d\n", SSL_get_error(*curssl, ret)); return -1; } } else { if((ret = SSL_accept(*curssl)) <=0 ) { ERR_print_errors_fp(stderr); printf("ssl error %d\n", SSL_get_error(*curssl, ret)); return -1; } } return check_cert(*curssl); }