コード例 #1
0
void dtls_try_with_key_mtu(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx,
		gnutls_sign_algorithm_t server_sign_algo,
		gnutls_sign_algorithm_t client_sign_algo,
		const gnutls_datum_t *serv_cert,
		const gnutls_datum_t *serv_key,
		const gnutls_datum_t *client_cert,
		const gnutls_datum_t *client_key,
		unsigned cert_flags,
		unsigned smtu)
{
	int ret;
	char buffer[256];
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_anon_server_credentials_t s_anoncred;
	gnutls_dh_params_t dh_params;
	const gnutls_datum_t p3 =
	    { (unsigned char *) pkcs3, strlen(pkcs3) };
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_anon_client_credentials_t c_anoncred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN, version;

	/* General init. */
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	reset_buffers();
	/* Init server */
	gnutls_anon_allocate_server_credentials(&s_anoncred);
	gnutls_certificate_allocate_credentials(&serverx509cred);

	ret = gnutls_certificate_set_x509_key_mem(serverx509cred,
					    serv_cert, serv_key,
					    GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fail("Could not set key/cert: %s\n", gnutls_strerror(ret));
	}

	gnutls_dh_params_init(&dh_params);
	gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM);
	gnutls_certificate_set_dh_params(serverx509cred, dh_params);
	gnutls_anon_set_server_dh_params(s_anoncred, dh_params);

	assert(gnutls_init(&server, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK)>=0);
	assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				      serverx509cred)>=0);
	assert(gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred)>=0);

	assert(gnutls_priority_set_direct(server,
					  "NORMAL:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519",
					   NULL)>=0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_pull_timeout_function(server, server_pull_timeout_func);
	gnutls_transport_set_ptr(server, server);
	if (smtu)
		gnutls_dtls_set_mtu (server, smtu);

	/* Init client */

	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	if (cert_flags == USE_CERT) {
		ret = gnutls_certificate_set_x509_key_mem(clientx509cred,
						    client_cert, client_key,
						    GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fail("Could not set key/cert: %s\n", gnutls_strerror(ret));
		}
		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE);
	} else if (cert_flags == ASK_CERT) {
		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);
	}

#if 0
	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);
#endif

	ret = gnutls_init(&client, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
	if (ret < 0)
		exit(1);

	assert(gnutls_anon_allocate_client_credentials(&c_anoncred)>=0);
	assert(gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred)>=0);
	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				clientx509cred);
	if (ret < 0)
		exit(1);

	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_pull_timeout_function(client, client_pull_timeout_func);

	gnutls_transport_set_ptr(client, client);
	if (smtu)
		gnutls_dtls_set_mtu (client, smtu);

	ret = gnutls_priority_set_direct(client, client_prio, NULL);
	if (ret < 0) {
		exit(1);
	}
	success("negotiating %s\n", name);
	HANDSHAKE_DTLS(client, server);

	if (gnutls_kx_get(client) != client_kx) {
		fail("%s: got unexpected key exchange algorithm: %s (expected %s)\n", name, gnutls_kx_get_name(gnutls_kx_get(client)),
			gnutls_kx_get_name(client_kx));
		exit(1);
	}


	/* test signature algorithm match */
	version = gnutls_protocol_get_version(client);
	if (version >= GNUTLS_DTLS1_2) {
		ret = gnutls_sign_algorithm_get(server);
		if (ret != (int)server_sign_algo) {
			fail("%s: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get_client(server);
		if (ret != (int)client_sign_algo) {
			fail("%s: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get(client);
		if (ret != (int)server_sign_algo) {
			fail("%s: cl: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get_client(client);
		if (ret != (int)client_sign_algo) {
			fail("%s: cl: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}
	}

	gnutls_record_send(server, MSG, strlen(MSG));

	ret = gnutls_record_recv(client, buffer, sizeof(buffer));
	if (ret == 0) {
		fail("client: Peer has closed the TLS connection\n");
		exit(1);
	} else if (ret < 0) {
		fail("client: Error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	if (ret != strlen(MSG) || memcmp(MSG, buffer, ret) != 0) {
		fail("client: Error in data received. Expected %d, got %d\n", (int)strlen(MSG), ret);
		exit(1);
	}

	gnutls_bye(client, GNUTLS_SHUT_RDWR);
	gnutls_bye(server, GNUTLS_SHUT_RDWR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);
	gnutls_anon_free_server_credentials(s_anoncred);
	gnutls_anon_free_client_credentials(c_anoncred);
	gnutls_dh_params_deinit(dh_params);
}
コード例 #2
0
ファイル: common.c プロジェクト: randombit/hacrypto
int print_info(gnutls_session_t session, int verbose, int print_cert)
{
	const char *tmp;
	gnutls_credentials_type_t cred;
	gnutls_kx_algorithm_t kx;
	unsigned char session_id[33];
	size_t session_id_size = sizeof(session_id);
	gnutls_srtp_profile_t srtp_profile;
	gnutls_datum_t p;
	char *desc;
	int rc;

	desc = gnutls_session_get_desc(session);
	printf("- Description: %s\n", desc);
	gnutls_free(desc);

	/* print session ID */
	gnutls_session_get_id(session, session_id, &session_id_size);
	printf("- Session ID: %s\n",
	       raw_to_string(session_id, session_id_size));

	/* print the key exchange's algorithm name
	 */
	kx = gnutls_kx_get(session);

	cred = gnutls_auth_get_type(session);
	switch (cred) {
#ifdef ENABLE_ANON
	case GNUTLS_CRD_ANON:
		if (kx == GNUTLS_KX_ANON_ECDH)
			print_ecdh_info(session, "Anonymous ");
		else
			print_dh_info(session, "Anonymous ", verbose);
		break;
#endif
#ifdef ENABLE_SRP
	case GNUTLS_CRD_SRP:
		/* This should be only called in server
		 * side.
		 */
		if (gnutls_srp_server_get_username(session) != NULL)
			printf("- SRP authentication. Connected as '%s'\n",
			       gnutls_srp_server_get_username(session));
		break;
#endif
#ifdef ENABLE_PSK
	case GNUTLS_CRD_PSK:
		/* This returns NULL in server side.
		 */
		if (gnutls_psk_client_get_hint(session) != NULL)
			printf("- PSK authentication. PSK hint '%s'\n",
			       gnutls_psk_client_get_hint(session));
		/* This returns NULL in client side.
		 */
		if (gnutls_psk_server_get_username(session) != NULL)
			printf("- PSK authentication. Connected as '%s'\n",
			       gnutls_psk_server_get_username(session));
		if (kx == GNUTLS_KX_DHE_PSK)
			print_dh_info(session, "Ephemeral ", verbose);
		if (kx == GNUTLS_KX_ECDHE_PSK)
			print_ecdh_info(session, "Ephemeral ");
		break;
#endif
	case GNUTLS_CRD_IA:
		printf("- TLS/IA authentication\n");
		break;
	case GNUTLS_CRD_CERTIFICATE:
		{
			char dns[256];
			size_t dns_size = sizeof(dns);
			unsigned int type;

			/* This fails in client side */
			if (gnutls_server_name_get
			    (session, dns, &dns_size, &type, 0) == 0) {
				printf("- Given server name[%d]: %s\n",
				       type, dns);
			}
		}

		if (print_cert)
			print_cert_info(session, verbose, print_cert);

		if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
			print_dh_info(session, "Ephemeral ", verbose);
		else if (kx == GNUTLS_KX_ECDHE_RSA
			 || kx == GNUTLS_KX_ECDHE_ECDSA)
			print_ecdh_info(session, "Ephemeral ");
	}

	tmp =
	    SU(gnutls_protocol_get_name
	       (gnutls_protocol_get_version(session)));
	printf("- Version: %s\n", tmp);

	tmp = SU(gnutls_kx_get_name(kx));
	printf("- Key Exchange: %s\n", tmp);

	if (gnutls_sign_algorithm_get(session) != GNUTLS_SIGN_UNKNOWN) {
		tmp =
		    SU(gnutls_sign_get_name
		       (gnutls_sign_algorithm_get(session)));
		printf("- Server Signature: %s\n", tmp);
	}

	if (gnutls_sign_algorithm_get_client(session) !=
	    GNUTLS_SIGN_UNKNOWN) {
		tmp =
		    SU(gnutls_sign_get_name
		       (gnutls_sign_algorithm_get_client(session)));
		printf("- Client Signature: %s\n", tmp);
	}

	tmp = SU(gnutls_cipher_get_name(gnutls_cipher_get(session)));
	printf("- Cipher: %s\n", tmp);

	tmp = SU(gnutls_mac_get_name(gnutls_mac_get(session)));
	printf("- MAC: %s\n", tmp);

	tmp =
	    SU(gnutls_compression_get_name
	       (gnutls_compression_get(session)));
	printf("- Compression: %s\n", tmp);

#ifdef ENABLE_DTLS_SRTP
	rc = gnutls_srtp_get_selected_profile(session, &srtp_profile);
	if (rc == 0)
		printf("- SRTP profile: %s\n",
		       gnutls_srtp_get_profile_name(srtp_profile));
#endif

#ifdef ENABLE_ALPN
	rc = gnutls_alpn_get_selected_protocol(session, &p);
	if (rc == 0)
		printf("- Application protocol: %.*s\n", p.size, p.data);
#endif

	if (verbose) {
		gnutls_datum_t cb;

		rc = gnutls_session_channel_binding(session,
						    GNUTLS_CB_TLS_UNIQUE,
						    &cb);
		if (rc)
			fprintf(stderr, "Channel binding error: %s\n",
				gnutls_strerror(rc));
		else {
			size_t i;

			printf("- Channel binding 'tls-unique': ");
			for (i = 0; i < cb.size; i++)
				printf("%02x", cb.data[i]);
			printf("\n");
		}
	}

	/* Warning: Do not print anything more here. The 'Compression:'
	   output MUST be the last non-verbose output.  This is used by
	   Emacs starttls.el code. */

	fflush(stdout);

	return 0;
}
コード例 #3
0
void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx,
		gnutls_sign_algorithm_t server_sign_algo,
		gnutls_sign_algorithm_t client_sign_algo,
		const gnutls_datum_t *serv_cert,
		const gnutls_datum_t *serv_key,
		const gnutls_datum_t *client_cert,
		const gnutls_datum_t *client_key,
		unsigned cert_flags,
		unsigned exp_group,
		gnutls_certificate_type_t server_ctype,
		gnutls_certificate_type_t client_ctype)
{
	int ret;
	char buffer[256];
	/* Server stuff. */
	gnutls_certificate_credentials_t server_cred;
	gnutls_anon_server_credentials_t s_anoncred;
	gnutls_dh_params_t dh_params;
	const gnutls_datum_t p3 =
	    { (unsigned char *) pkcs3, strlen(pkcs3) };
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t client_cred;
	gnutls_anon_client_credentials_t c_anoncred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN, version;
	const char *err;

	/* General init. */
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	reset_buffers();
	/* Init server */
	assert(gnutls_anon_allocate_server_credentials(&s_anoncred)>=0);
	assert(gnutls_certificate_allocate_credentials(&server_cred)>=0);

	// Set server crt creds based on ctype
	switch (server_ctype) {
		case GNUTLS_CRT_X509:
			ret = gnutls_certificate_set_x509_key_mem(server_cred,
									serv_cert, serv_key,
									GNUTLS_X509_FMT_PEM);
			break;
		case GNUTLS_CRT_RAWPK:
			ret = gnutls_certificate_set_rawpk_key_mem(server_cred,
									serv_cert, serv_key, GNUTLS_X509_FMT_PEM, NULL, 0,
									NULL, 0, 0);
			break;
		default:
			ret = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
	}

	if (ret < 0) {
		fail("Could not set key/cert: %s\n", gnutls_strerror(ret));
	}

	gnutls_dh_params_init(&dh_params);
	gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM);
	gnutls_certificate_set_dh_params(server_cred, dh_params);
	gnutls_anon_set_server_dh_params(s_anoncred, dh_params);

	assert(gnutls_init(&server, GNUTLS_SERVER | GNUTLS_ENABLE_RAWPK)>=0);
	assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				      server_cred)>=0);
	assert(gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred)>=0);

	if (server_priority)
		assert(gnutls_priority_set_direct(server, server_priority, NULL) >= 0);
	else
		assert(gnutls_priority_set_direct(server,
				   "NORMAL:+VERS-SSL3.0:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519:+CTYPE-ALL",
				   NULL)>=0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);

	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&client_cred);
	if (ret < 0)
		exit(1);

	if (cert_flags == USE_CERT) {
		// Set client crt creds based on ctype
		switch (client_ctype) {
			case GNUTLS_CRT_X509:
				gnutls_certificate_set_x509_key_mem(client_cred,
										client_cert, client_key,
										GNUTLS_X509_FMT_PEM);
				break;
			case GNUTLS_CRT_RAWPK:
				gnutls_certificate_set_rawpk_key_mem(client_cred,
									client_cert, client_key, GNUTLS_X509_FMT_PEM, NULL, 0,
									NULL, 0, 0);
				break;
			default:
				fail("Illegal client certificate type given\n");
		}

		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE);
	} else if (cert_flags == ASK_CERT) {
		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);
	}

#if 0
	ret = gnutls_certificate_set_x509_trust_mem(client_cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);
#endif
	ret = gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_ENABLE_RAWPK);
	if (ret < 0)
		exit(1);


	assert(gnutls_anon_allocate_client_credentials(&c_anoncred)>=0);
	assert(gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred)>=0);
	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				client_cred);
	if (ret < 0)
		exit(1);

	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	ret = gnutls_priority_set_direct(client, client_prio, &err);
	if (ret < 0) {
		if (ret == GNUTLS_E_INVALID_REQUEST)
			fprintf(stderr, "Error in %s\n", err);
		exit(1);
	}
	success("negotiating %s\n", name);
	HANDSHAKE(client, server);

	if (gnutls_kx_get(client) != client_kx) {
		fail("%s: got unexpected key exchange algorithm: %s (expected %s)\n", name, gnutls_kx_get_name(gnutls_kx_get(client)),
			gnutls_kx_get_name(client_kx));
		exit(1);
	}

	/* test signature algorithm match */
	version = gnutls_protocol_get_version(client);
	if (version >= GNUTLS_TLS1_2) {
		ret = gnutls_sign_algorithm_get(server);
		if (ret != (int)server_sign_algo) {
			fail("%s: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get_client(server);
		if (ret != (int)client_sign_algo) {
			fail("%s: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get(client);
		if (ret != (int)server_sign_algo) {
			fail("%s: cl: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get_client(client);
		if (ret != (int)client_sign_algo) {
			fail("%s: cl: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}
	}

	if (exp_group != 0) {
		ret = gnutls_group_get(server);
		if (ret != (int)exp_group) {
			fail("%s: got unexpected server group: %d/%s\n", name, ret, gnutls_group_get_name(ret));
		}

		ret = gnutls_group_get(client);
		if (ret != (int)exp_group) {
			fail("%s: got unexpected client group: %d/%s\n", name, ret, gnutls_group_get_name(ret));
		}
	}

	gnutls_record_send(server, MSG, strlen(MSG));

	ret = gnutls_record_recv(client, buffer, sizeof(buffer));
	if (ret == 0) {
		fail("client: Peer has closed the TLS connection\n");
		exit(1);
	} else if (ret < 0) {
		fail("client: Error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	if (ret != strlen(MSG) || memcmp(MSG, buffer, ret) != 0) {
		fail("client: Error in data received. Expected %d, got %d\n", (int)strlen(MSG), ret);
		exit(1);
	}

	gnutls_bye(client, GNUTLS_SHUT_RDWR);
	gnutls_bye(server, GNUTLS_SHUT_RDWR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(server_cred);
	gnutls_certificate_free_credentials(client_cred);
	gnutls_anon_free_server_credentials(s_anoncred);
	gnutls_anon_free_client_credentials(c_anoncred);
	gnutls_dh_params_deinit(dh_params);
}