示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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 */
}
示例#4
0
/* 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;
}
示例#5
0
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;
}
示例#6
0
文件: ciphers.c 项目: Lukasa/openssl
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);
}
示例#7
0
/* 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;
}
示例#8
0
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;
}
示例#9
0
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;
}