NOEXPORT int auth_init(SERVICE_OPTIONS *section) { int result; result=load_cert(section); #ifndef OPENSSL_NO_PSK if(section->psk_keys) { if(section->option.client) SSL_CTX_set_psk_client_callback(section->ctx, psk_client_callback); else SSL_CTX_set_psk_server_callback(section->ctx, psk_server_callback); result=0; } #endif /* !defined(OPENSSL_NO_PSK) */ return result; }
int main(void) { SSL_CTX *ctx = SSL_CTX_new(DTLS_method()); STACK_OF(SSL_CIPHER) *ciphers; int i, rv = 0; SSL_CTX_set_psk_server_callback(ctx, srvr_psk_callback); SSL_CTX_set_psk_client_callback(ctx, clnt_psk_callback); SSL_CTX_set_security_level(ctx, 0); /* We only care about iterating over each enc/mac; we don't * want to repeat the test for each auth/kx variant. * So keep life simple and only do (non-DH) PSK. */ if (!SSL_CTX_set_cipher_list(ctx, "PSK")) { fprintf(stderr, "Failed to set PSK cipher list\n"); goto out; } ciphers = SSL_CTX_get_ciphers(ctx); for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i); const char *cipher_name = SSL_CIPHER_get_name(cipher); /* As noted above, only one test for each enc/mac variant. */ if (strncmp(cipher_name, "PSK-", 4)) continue; rv = mtu_test(ctx, cipher_name, 0); if (!rv) break; printf("DTLS MTU test OK for %s\n", cipher_name); if (rv == 1) continue; /* mtu_test() returns 2 if it used Encrypt-then-MAC */ rv = mtu_test(ctx, cipher_name, 1); if (!rv) break; printf("DTLS MTU test OK for %s without Encrypt-then-MAC\n", cipher_name); } out: SSL_CTX_free(ctx); return !rv; }
NOEXPORT int auth_init(SERVICE_OPTIONS *section) { int cert_needed=1, key_needed=1; #ifndef OPENSSL_NO_PSK if(section->psk_keys) { if(section->option.client) SSL_CTX_set_psk_client_callback(section->ctx, psk_client_callback); else SSL_CTX_set_psk_server_callback(section->ctx, psk_server_callback); } #endif /* !defined(OPENSSL_NO_PSK) */ /* load the certificate and private key */ if(!section->cert || !section->key) { s_log(LOG_DEBUG, "No certificate or private key specified"); return 0; /* OK */ } #ifndef OPENSSL_NO_ENGINE if(section->engine) { /* try to use the engine first */ cert_needed=load_cert_engine(section); key_needed=load_key_engine(section); } #endif if(cert_needed && load_cert_file(section)) return 1; /* FAILED */ if(key_needed && load_key_file(section)) return 1; /* FAILED */ /* validate the private key against the certificate */ if(!SSL_CTX_check_private_key(section->ctx)) { sslerror("Private key does not match the certificate"); return 1; /* FAILED */ } s_log(LOG_DEBUG, "Private key check succeeded"); return 0; /* OK */ }
/* Create a socket and connect it to 'ip' on port 'port'. * Returns -1 on failure (ip is NULL, socket creation/connection error) * Returns sock number on success. */ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking) { mosq_sock_t sock = INVALID_SOCKET; int rc; #ifdef WITH_TLS int ret; BIO *bio; #endif if(!mosq || !host || !port) return MOSQ_ERR_INVAL; rc = _mosquitto_try_connect(mosq, host, port, &sock, bind_address, blocking); if(rc > 0) return rc; #ifdef WITH_TLS if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){ #if OPENSSL_VERSION_NUMBER >= 0x10001000L if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1.2")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_2_client_method()); }else if(!strcmp(mosq->tls_version, "tlsv1.1")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_1_client_method()); }else if(!strcmp(mosq->tls_version, "tlsv1")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method()); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version); COMPAT_CLOSE(sock); return MOSQ_ERR_INVAL; } #else if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method()); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version); COMPAT_CLOSE(sock); return MOSQ_ERR_INVAL; } #endif if(!mosq->ssl_ctx){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context."); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } #if OPENSSL_VERSION_NUMBER >= 0x10000000 /* Disable compression */ SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_COMPRESSION); #endif #ifdef SSL_MODE_RELEASE_BUFFERS /* Use even less memory per SSL connection. */ SSL_CTX_set_mode(mosq->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); #endif if(mosq->tls_ciphers){ ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers); if(ret == 0){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } if(mosq->tls_cafile || mosq->tls_capath){ ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath); if(ret == 0){ #ifdef WITH_BROKER if(mosq->tls_cafile && mosq->tls_capath){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); }else if(mosq->tls_cafile){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath); } #else if(mosq->tls_cafile && mosq->tls_capath){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); }else if(mosq->tls_cafile){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath); } #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } if(mosq->tls_cert_reqs == 0){ SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_NONE, NULL); }else{ SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_PEER, _mosquitto_server_certificate_verify); } if(mosq->tls_pw_callback){ SSL_CTX_set_default_passwd_cb(mosq->ssl_ctx, mosq->tls_pw_callback); SSL_CTX_set_default_passwd_cb_userdata(mosq->ssl_ctx, mosq); } if(mosq->tls_certfile){ ret = SSL_CTX_use_certificate_chain_file(mosq->ssl_ctx, mosq->tls_certfile); if(ret != 1){ #ifdef WITH_BROKER _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate, check bridge_certfile \"%s\".", mosq->tls_certfile); #else _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile); #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } if(mosq->tls_keyfile){ ret = SSL_CTX_use_PrivateKey_file(mosq->ssl_ctx, mosq->tls_keyfile, SSL_FILETYPE_PEM); if(ret != 1){ #ifdef WITH_BROKER _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file, check bridge_keyfile \"%s\".", mosq->tls_keyfile); #else _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile); #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } ret = SSL_CTX_check_private_key(mosq->ssl_ctx); if(ret != 1){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent."); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } #ifdef REAL_WITH_TLS_PSK }else if(mosq->tls_psk){ SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback); #endif } mosq->ssl = SSL_new(mosq->ssl_ctx); if(!mosq->ssl){ COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq); bio = BIO_new_socket(sock, BIO_NOCLOSE); if(!bio){ COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } SSL_set_bio(mosq->ssl, bio, bio); mosq->sock = sock; if(mosquitto__socket_connect_tls(mosq)){ return MOSQ_ERR_TLS; } } #endif mosq->sock = sock; return rc; }
int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) { STACK_OF(SSL_CIPHER) *ciphers; method_const SSL_METHOD *dtls_method; SSL_SESSION *dtls_session; SSL *dtls_ssl; BIO *dtls_bio; int dtlsver = DTLS1_BAD_VER; const char *cipher = vpninfo->dtls_cipher; #ifdef HAVE_DTLS12 if (!strcmp(cipher, "OC-DTLS1_2-AES128-GCM")) { dtlsver = DTLS1_2_VERSION; cipher = "AES128-GCM-SHA256"; } else if (!strcmp(cipher, "OC-DTLS1_2-AES256-GCM")) { dtlsver = DTLS1_2_VERSION; cipher = "AES256-GCM-SHA384"; #ifndef OPENSSL_NO_PSK } else if (!strcmp(cipher, "PSK-NEGOTIATE")) { dtlsver = 0; /* Let it negotiate */ #endif } #endif if (!vpninfo->dtls_ctx) { #ifdef HAVE_DTLS12 dtls_method = DTLS_client_method(); #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) if (dtlsver == DTLS1_BAD_VER) dtls_method = DTLSv1_client_method(); #ifdef HAVE_DTLS12 else if (dtlsver == DTLS1_2_VERSION) dtls_method = DTLSv1_2_client_method(); #endif #endif vpninfo->dtls_ctx = SSL_CTX_new(dtls_method); if (!vpninfo->dtls_ctx) { vpn_progress(vpninfo, PRG_ERR, _("Initialise DTLSv1 CTX failed\n")); openconnect_report_ssl_errors(vpninfo); vpninfo->dtls_attempt_period = 0; return -EINVAL; } if (dtlsver) { #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) if (dtlsver == DTLS1_BAD_VER) SSL_CTX_set_options(vpninfo->dtls_ctx, SSL_OP_CISCO_ANYCONNECT); #else if (!SSL_CTX_set_min_proto_version(vpninfo->dtls_ctx, dtlsver) || !SSL_CTX_set_max_proto_version(vpninfo->dtls_ctx, dtlsver)) { vpn_progress(vpninfo, PRG_ERR, _("Set DTLS CTX version failed\n")); openconnect_report_ssl_errors(vpninfo); SSL_CTX_free(vpninfo->dtls_ctx); vpninfo->dtls_ctx = NULL; vpninfo->dtls_attempt_period = 0; return -EINVAL; } #endif #if defined (HAVE_DTLS12) && !defined(OPENSSL_NO_PSK) } else { SSL_CTX_set_psk_client_callback(vpninfo->dtls_ctx, psk_callback); /* For PSK we override the DTLS master secret with one derived * from the HTTPS session. */ if (!SSL_export_keying_material(vpninfo->https_ssl, vpninfo->dtls_secret, PSK_KEY_SIZE, PSK_LABEL, PSK_LABEL_SIZE, NULL, 0, 0)) { vpn_progress(vpninfo, PRG_ERR, _("Failed to generate DTLS key\n")); openconnect_report_ssl_errors(vpninfo); SSL_CTX_free(vpninfo->dtls_ctx); vpninfo->dtls_ctx = NULL; vpninfo->dtls_attempt_period = 0; return -EINVAL; } SSL_CTX_add_client_custom_ext(vpninfo->dtls_ctx, DTLS_APP_ID_EXT, pskident_add, pskident_free, vpninfo, pskident_parse, vpninfo); /* For SSL_CTX_set_cipher_list() */ cipher = "PSK"; #endif } /* If we don't readahead, then we do short reads and throw away the tail of data packets. */ SSL_CTX_set_read_ahead(vpninfo->dtls_ctx, 1); if (!SSL_CTX_set_cipher_list(vpninfo->dtls_ctx, cipher)) { vpn_progress(vpninfo, PRG_ERR, _("Set DTLS cipher list failed\n")); SSL_CTX_free(vpninfo->dtls_ctx); vpninfo->dtls_ctx = NULL; vpninfo->dtls_attempt_period = 0; return -EINVAL; } } dtls_ssl = SSL_new(vpninfo->dtls_ctx); SSL_set_connect_state(dtls_ssl); SSL_set_app_data(dtls_ssl, vpninfo); if (dtlsver) { ciphers = SSL_get_ciphers(dtls_ssl); if (dtlsver != 0 && sk_SSL_CIPHER_num(ciphers) != 1) { vpn_progress(vpninfo, PRG_ERR, _("Not precisely one DTLS cipher\n")); SSL_CTX_free(vpninfo->dtls_ctx); SSL_free(dtls_ssl); vpninfo->dtls_ctx = NULL; vpninfo->dtls_attempt_period = 0; return -EINVAL; } /* We're going to "resume" a session which never existed. Fake it... */ dtls_session = generate_dtls_session(vpninfo, dtlsver, sk_SSL_CIPHER_value(ciphers, 0)); if (!dtls_session) { SSL_CTX_free(vpninfo->dtls_ctx); SSL_free(dtls_ssl); vpninfo->dtls_ctx = NULL; vpninfo->dtls_attempt_period = 0; return -EINVAL; } /* Add the generated session to the SSL */ if (!SSL_set_session(dtls_ssl, dtls_session)) { vpn_progress(vpninfo, PRG_ERR, _("SSL_set_session() failed with old protocol version 0x%x\n" "Are you using a version of OpenSSL older than 0.9.8m?\n" "See http://rt.openssl.org/Ticket/Display.html?id=1751\n" "Use the --no-dtls command line option to avoid this message\n"), DTLS1_BAD_VER); SSL_CTX_free(vpninfo->dtls_ctx); SSL_free(dtls_ssl); vpninfo->dtls_ctx = NULL; vpninfo->dtls_attempt_period = 0; SSL_SESSION_free(dtls_session); return -EINVAL; } /* We don't need our own refcount on it any more */ SSL_SESSION_free(dtls_session); } dtls_bio = BIO_new_socket(dtls_fd, BIO_NOCLOSE); /* Set non-blocking */ BIO_set_nbio(dtls_bio, 1); SSL_set_bio(dtls_ssl, dtls_bio, dtls_bio); vpninfo->dtls_ssl = dtls_ssl; return 0; }
int ciphers_main(int argc, char **argv) { SSL_CTX *ctx = NULL; SSL *ssl = NULL; STACK_OF(SSL_CIPHER) *sk = NULL; const SSL_METHOD *meth = TLS_server_method(); int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0; #ifndef OPENSSL_NO_SSL_TRACE int stdname = 0; #endif #ifndef OPENSSL_NO_PSK int psk = 0; #endif #ifndef OPENSSL_NO_SRP int srp = 0; #endif const char *p; char *ciphers = NULL, *prog; char buf[512]; OPTION_CHOICE o; int min_version = 0, max_version = 0; prog = opt_init(argc, argv, ciphers_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(ciphers_options); ret = 0; goto end; case OPT_V: verbose = 1; break; case OPT_UPPER_V: verbose = Verbose = 1; break; case OPT_S: use_supported = 1; break; case OPT_STDNAME: #ifndef OPENSSL_NO_SSL_TRACE stdname = verbose = 1; #endif break; case OPT_SSL3: min_version = SSL3_VERSION; max_version = SSL3_VERSION; break; case OPT_TLS1: min_version = TLS1_VERSION; max_version = TLS1_VERSION; break; case OPT_TLS1_1: min_version = TLS1_1_VERSION; max_version = TLS1_1_VERSION; break; case OPT_TLS1_2: min_version = TLS1_2_VERSION; max_version = TLS1_2_VERSION; break; case OPT_TLS1_3: min_version = TLS1_3_VERSION; max_version = TLS1_3_VERSION; break; case OPT_PSK: #ifndef OPENSSL_NO_PSK psk = 1; #endif break; case OPT_SRP: #ifndef OPENSSL_NO_SRP srp = 1; #endif break; } } argv = opt_rest(); argc = opt_num_rest(); if (argc == 1) ciphers = *argv; else if (argc != 0) goto opthelp; ctx = SSL_CTX_new(meth); if (ctx == NULL) goto err; if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) goto err; if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) goto err; #ifndef OPENSSL_NO_PSK if (psk) SSL_CTX_set_psk_client_callback(ctx, dummy_psk); #endif #ifndef OPENSSL_NO_SRP if (srp) SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp); #endif if (ciphers != NULL) { if (!SSL_CTX_set_cipher_list(ctx, ciphers)) { BIO_printf(bio_err, "Error in cipher list\n"); goto err; } } ssl = SSL_new(ctx); if (ssl == NULL) goto err; if (use_supported) sk = SSL_get1_supported_ciphers(ssl); else sk = SSL_get_ciphers(ssl); if (!verbose) { for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i); p = SSL_CIPHER_get_name(c); if (p == NULL) break; if (i != 0) BIO_printf(bio_out, ":"); BIO_printf(bio_out, "%s", p); } BIO_printf(bio_out, "\n"); } else { for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { const SSL_CIPHER *c; c = sk_SSL_CIPHER_value(sk, i); if (Verbose) { unsigned long id = SSL_CIPHER_get_id(c); int id0 = (int)(id >> 24); int id1 = (int)((id >> 16) & 0xffL); int id2 = (int)((id >> 8) & 0xffL); int id3 = (int)(id & 0xffL); if ((id & 0xff000000L) == 0x03000000L) BIO_printf(bio_out, " 0x%02X,0x%02X - ", id2, id3); /* SSL3 * cipher */ else BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */ } #ifndef OPENSSL_NO_SSL_TRACE if (stdname) { const char *nm = SSL_CIPHER_standard_name(c); if (nm == NULL) nm = "UNKNOWN"; BIO_printf(bio_out, "%s - ", nm); } #endif BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof buf)); } } ret = 0; goto end; err: ERR_print_errors(bio_err); end: if (use_supported) sk_SSL_CIPHER_free(sk); SSL_CTX_free(ctx); SSL_free(ssl); return (ret); }
/* Create a socket and connect it to 'ip' on port 'port'. * Returns -1 on failure (ip is NULL, socket creation/connection error) * Returns sock number on success. */ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port) { int sock = INVALID_SOCKET; #ifndef WIN32 int opt; #endif struct addrinfo hints; struct addrinfo *ainfo, *rp; int s; #ifdef WIN32 uint32_t val = 1; #endif #ifdef WITH_TLS int ret; BIO *bio; #endif if(!mosq || !host || !port) return MOSQ_ERR_INVAL; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_ADDRCONFIG; hints.ai_socktype = SOCK_STREAM; s = getaddrinfo(host, NULL, &hints, &ainfo); if(s) return MOSQ_ERR_UNKNOWN; for(rp = ainfo; rp != NULL; rp = rp->ai_next){ sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if(sock == INVALID_SOCKET) continue; if(rp->ai_family == PF_INET){ ((struct sockaddr_in *)rp->ai_addr)->sin_port = htons(port); }else if(rp->ai_family == PF_INET6){ ((struct sockaddr_in6 *)rp->ai_addr)->sin6_port = htons(port); }else{ continue; } if(connect(sock, rp->ai_addr, rp->ai_addrlen) != -1){ break; } #ifdef WIN32 errno = WSAGetLastError(); #endif COMPAT_CLOSE(sock); } if(!rp){ return MOSQ_ERR_ERRNO; } freeaddrinfo(ainfo); /* Set non-blocking */ #ifndef WIN32 opt = fcntl(sock, F_GETFL, 0); if(opt == -1 || fcntl(sock, F_SETFL, opt | O_NONBLOCK) == -1){ #ifdef WITH_TLS if(mosq->ssl){ SSL_shutdown(mosq->ssl); SSL_free(mosq->ssl); mosq->ssl = NULL; } if(mosq->ssl_ctx){ SSL_CTX_free(mosq->ssl_ctx); mosq->ssl_ctx = NULL; } #endif COMPAT_CLOSE(sock); return MOSQ_ERR_ERRNO; } #else if(ioctlsocket(sock, FIONBIO, &val)){ errno = WSAGetLastError(); #ifdef WITH_TLS if(mosq->ssl){ SSL_shutdown(mosq->ssl); SSL_free(mosq->ssl); mosq->ssl = NULL; } if(mosq->ssl_ctx){ SSL_CTX_free(mosq->ssl_ctx); mosq->ssl_ctx = NULL; } #endif COMPAT_CLOSE(sock); return MOSQ_ERR_ERRNO; } #endif #ifdef WITH_TLS if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){ if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method()); if(!mosq->ssl_ctx){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context."); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } }else{ COMPAT_CLOSE(sock); return MOSQ_ERR_INVAL; } if(mosq->tls_ciphers){ ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers); if(ret == 0){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } if(mosq->tls_cafile || mosq->tls_capath){ ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath); if(ret == 0){ #ifdef WITH_BROKER if(mosq->tls_cafile && mosq->tls_capath){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); }else if(mosq->tls_cafile){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath); } #else if(mosq->tls_cafile && mosq->tls_capath){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); }else if(mosq->tls_cafile){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath); } #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } if(mosq->tls_cert_reqs == 0){ SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_NONE, NULL); }else{ SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_PEER, NULL); } if(mosq->tls_pw_callback){ SSL_CTX_set_default_passwd_cb(mosq->ssl_ctx, mosq->tls_pw_callback); SSL_CTX_set_default_passwd_cb_userdata(mosq->ssl_ctx, mosq); } if(mosq->tls_certfile){ ret = SSL_CTX_use_certificate_file(mosq->ssl_ctx, mosq->tls_certfile, SSL_FILETYPE_PEM); if(ret != 1){ #ifdef WITH_BROKER _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate, check bridge_certfile \"%s\".", mosq->tls_certfile); #else _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile); #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } if(mosq->tls_keyfile){ ret = SSL_CTX_use_PrivateKey_file(mosq->ssl_ctx, mosq->tls_keyfile, SSL_FILETYPE_PEM); if(ret != 1){ #ifdef WITH_BROKER _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file, check bridge_keyfile \"%s\".", mosq->tls_keyfile); #else _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile); #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } ret = SSL_CTX_check_private_key(mosq->ssl_ctx); if(ret != 1){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent."); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } #ifdef WITH_TLS_PSK }else if(mosq->tls_psk){ SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback); #endif } mosq->ssl = SSL_new(mosq->ssl_ctx); if(!mosq->ssl){ COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq); bio = BIO_new_socket(sock, BIO_NOCLOSE); if(!bio){ COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } SSL_set_bio(mosq->ssl, bio, bio); ret = SSL_connect(mosq->ssl); if(ret != 1){ ret = SSL_get_error(mosq->ssl, ret); if(ret == SSL_ERROR_WANT_READ){ mosq->want_read = true; }else if(ret == SSL_ERROR_WANT_WRITE){ mosq->want_write = true; }else{ COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } } #endif mosq->sock = sock; return MOSQ_ERR_SUCCESS; }
static int _tls_session_init_client(tls_session_t *s, int sockfd, const tls_init_config_t *cfg) { int ret; SSL_METHOD *method; #if defined(CYASSL_DTLS) method = DTLSv1_client_method(); #elif !defined(NO_TLS) method = SSLv23_client_method(); #else method = SSLv3_client_method(); #endif s->ctx = SSL_CTX_new(method); #ifndef NO_PSK SSL_CTX_set_psk_client_callback(s->ctx, my_psk_client_cb); #endif #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC) /* don't use EDH, can't sniff tmp keys */ SSL_CTX_set_cipher_list(s->ctx, "AES256-SHA"); #endif if (cfg->flags & TLS_CHECK_SERVER_CERT) { ASSERT(cfg->tls.client.ca_cert_size != 0); /* Load server certificates from buffer */ tls_d("Loading CA certificate file. Size: %d", cfg->tls.client.ca_cert_size); ret = CyaSSL_CTX_load_verify_buffer(s->ctx, cfg->tls.client.ca_cert, cfg->tls.client. ca_cert_size, SSL_FILETYPE_PEM); if (ret != SSL_SUCCESS) { tls_e("Unable to load CA certificate"); SSL_CTX_free(s->ctx); return -WM_FAIL; } } else { tls_d("Disabling certificate check"); SSL_CTX_set_verify(s->ctx, SSL_VERIFY_NONE, 0); } if (cfg->flags & TLS_USE_CLIENT_CERT) { /* The server wants to verify our certificates */ ASSERT(cfg->tls.client.client_cert_size != 0); ASSERT(cfg->tls.client.client_key_size != 0); /* Load client certificates and client private keys from buffer */ tls_d("Loading client certificate buffer. Size: %d", cfg->tls.client.client_cert_size); ret = CyaSSL_CTX_use_certificate_buffer(s->ctx, cfg->tls.client. client_cert, cfg->tls.client. client_cert_size, SSL_FILETYPE_PEM); if (ret != SSL_SUCCESS) { tls_e("Unable to load client certificate"); SSL_CTX_free(s->ctx); return -WM_FAIL; } tls_d("Loading client private key buffer. Size: %d", cfg->tls.client.client_key_size); ret = CyaSSL_CTX_use_PrivateKey_buffer(s->ctx, cfg->tls.client. client_key, cfg->tls.client. client_key_size, SSL_FILETYPE_PEM); if (ret != SSL_SUCCESS) { tls_e("Unable to load client key"); SSL_CTX_free(s->ctx); return -WM_FAIL; } } s->ssl = SSL_new(s->ctx); SSL_set_fd(s->ssl, sockfd); #ifdef CONFIG_WPA2_ENTP if (cfg->flags & TLS_WPA2_ENTP) { CyaSSL_SetIOSend(s->ctx, SSLSend); CyaSSL_SetIORecv(s->ctx, SSLReceive); } #endif #ifdef NON_BLOCKING tcp_set_nonblocking(&sockfd); NonBlockingSSL_Connect(s->ssl); #else #ifndef CYASSL_CALLBACKS tls_d("Starting SSL connect"); /* see note at top of README */ if (SSL_connect(s->ssl) != SSL_SUCCESS) { #ifdef CONFIG_ENABLE_ERROR_LOGS int err = SSL_get_error(s->ssl, 0); char buffer[80]; tls_e("err = %d, %s", err, ERR_error_string(err, buffer)); /* if you're getting an error here */ tls_e("SSL_connect failed"); #endif /* CONFIG_ENABLE_ERROR_LOGS */ SSL_free(s->ssl); SSL_CTX_free(s->ctx); return -WM_FAIL; } #else timeout.tv_sec = 2; timeout.tv_usec = 0; NonBlockingSSL_Connect(s->ssl); /* will keep retrying on timeout */ #endif #endif showPeer(s->ssl); s->session_setup_done = true; tls_d("SSL Connect success"); #ifdef CONFIG_WPA2_ENTP if (cfg->flags & TLS_WPA2_ENTP) return tls_session_success(s); #endif return WM_SUCCESS; }
void client_test(void* args) { SOCKET_T sockfd = 0; SSL_METHOD* method = 0; SSL_CTX* ctx = 0; SSL* ssl = 0; #ifdef TEST_RESUME SSL* sslResume = 0; SSL_SESSION* session = 0; char resumeMsg[] = "resuming cyassl!"; int resumeSz = sizeof(resumeMsg); #endif char msg[64] = "hello cyassl!"; char reply[1024]; int input; int msgSz = strlen(msg); int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; ((func_args*)args)->return_code = -1; /* error state */ #if defined(CYASSL_DTLS) method = DTLSv1_client_method(); #elif !defined(NO_TLS) method = SSLv23_client_method(); #else method = SSLv3_client_method(); #endif ctx = SSL_CTX_new(method); #ifndef NO_PSK SSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb); #endif #ifdef OPENSSL_EXTRA SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif #ifdef CYASSL_SNIFFER /* don't use EDH, can't sniff tmp keys */ SSL_CTX_set_cipher_list(ctx, "AES256-SHA"); #endif #ifndef NO_FILESYSTEM if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS) err_sys("can't load ca file"); #ifdef HAVE_ECC if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS) err_sys("can't load ca file"); #endif #else load_buffer(ctx, caCert, CYASSL_CA); #endif #ifdef VERIFY_CALLBACK SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify); #endif if (argc == 3) { /* ./client server securePort */ SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); /* TODO: add ca cert */ /* this is just to allow easy testing of other servers */ tcp_connect(&sockfd, argv[1], (short)atoi(argv[2])); } else if (argc == 1) { /* ./client // plain mode */ /* for client cert authentication if server requests */ #ifndef NO_FILESYSTEM if (SSL_CTX_use_certificate_file(ctx, cliCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load client cert file"); if (SSL_CTX_use_PrivateKey_file(ctx, cliKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load client key file"); #else load_buffer(ctx, cliCert, CYASSL_CERT); load_buffer(ctx, cliKey, CYASSL_KEY); #endif tcp_connect(&sockfd, yasslIP, yasslPort); } else if (argc == 2) { /* time passed in number of connects give average */ int times = atoi(argv[1]); int i = 0; double start = current_time(), avg; for (i = 0; i < times; i++) { tcp_connect(&sockfd, yasslIP, yasslPort); ssl = SSL_new(ctx); SSL_set_fd(ssl, sockfd); if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed"); SSL_shutdown(ssl); SSL_free(ssl); CloseSocket(sockfd); } avg = current_time() - start; avg /= times; avg *= 1000; /* milliseconds */ printf("SSL_connect avg took:%6.3f milliseconds\n", avg); SSL_CTX_free(ctx); ((func_args*)args)->return_code = 0; return; } else err_sys("usage: ./client server securePort"); ssl = SSL_new(ctx); SSL_set_fd(ssl, sockfd); if (argc != 3) CyaSSL_check_domain_name(ssl, "www.yassl.com"); #ifdef NON_BLOCKING tcp_set_nonblocking(&sockfd); NonBlockingSSL_Connect(ssl); #else #ifndef CYASSL_CALLBACKS if (SSL_connect(ssl) != SSL_SUCCESS) { /* see note at top of README */ int err = SSL_get_error(ssl, 0); char buffer[80]; printf("err = %d, %s\n", err, ERR_error_string(err, buffer)); err_sys("SSL_connect failed");/* if you're getting an error here */ } #else timeout.tv_sec = 2; timeout.tv_usec = 0; NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */ #endif #endif showPeer(ssl); if (argc == 3) { printf("SSL connect ok, sending GET...\n"); msgSz = 28; strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz); } if (SSL_write(ssl, msg, msgSz) != msgSz) err_sys("SSL_write failed"); input = SSL_read(ssl, reply, sizeof(reply)); if (input > 0) { reply[input] = 0; printf("Server response: %s\n", reply); if (argc == 3) { /* get html */ while (1) { input = SSL_read(ssl, reply, sizeof(reply)); if (input > 0) { reply[input] = 0; printf("%s\n", reply); } else break; } } } #ifdef TEST_RESUME #ifdef CYASSL_DTLS strncpy(msg, "break", 6); msgSz = (int)strlen(msg); /* try to send session close */ SSL_write(ssl, msg, msgSz); #endif session = SSL_get_session(ssl); sslResume = SSL_new(ctx); #endif SSL_shutdown(ssl); SSL_free(ssl); CloseSocket(sockfd); #ifdef TEST_RESUME #ifdef CYASSL_DTLS #ifdef USE_WINDOWS_API Sleep(500); #else sleep(1); #endif #endif if (argc == 3) tcp_connect(&sockfd, argv[1], (short)atoi(argv[2])); else tcp_connect(&sockfd, yasslIP, yasslPort); SSL_set_fd(sslResume, sockfd); SSL_set_session(sslResume, session); showPeer(sslResume); if (SSL_connect(sslResume) != SSL_SUCCESS) err_sys("SSL resume failed"); #ifdef OPENSSL_EXTRA if (SSL_session_reused(sslResume)) printf("reused session id\n"); else printf("didn't reuse session id!!!\n"); #endif if (SSL_write(sslResume, resumeMsg, resumeSz) != resumeSz) err_sys("SSL_write failed"); input = SSL_read(sslResume, reply, sizeof(reply)); if (input > 0) { reply[input] = 0; printf("Server resume response: %s\n", reply); } /* try to send session break */ SSL_write(sslResume, msg, msgSz); SSL_shutdown(sslResume); SSL_free(sslResume); #endif /* TEST_RESUME */ SSL_CTX_free(ctx); CloseSocket(sockfd); ((func_args*)args)->return_code = 0; }