Blame src/common.c

Packit Service 4684c1
/*
Packit Service 4684c1
 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
Packit Service 4684c1
 * Author: Nikos Mavrogiannopoulos
Packit Service 4684c1
 *
Packit Service 4684c1
 * This file is part of GnuTLS.
Packit Service 4684c1
 *
Packit Service 4684c1
 * GnuTLS is free software: you can redistribute it and/or modify
Packit Service 4684c1
 * it under the terms of the GNU General Public License as published by
Packit Service 4684c1
 * the Free Software Foundation, either version 3 of the License, or
Packit Service 4684c1
 * (at your option) any later version.
Packit Service 4684c1
 *
Packit Service 4684c1
 * GnuTLS is distributed in the hope that it will be useful,
Packit Service 4684c1
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 4684c1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 4684c1
 * GNU General Public License for more details.
Packit Service 4684c1
 *
Packit Service 4684c1
 * You should have received a copy of the GNU General Public License
Packit Service 4684c1
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
Packit Service 4684c1
 */
Packit Service 4684c1
Packit Service 4684c1
#include <config.h>
Packit Service 4684c1
Packit Service 4684c1
/* Work around problem reported in
Packit Service 4684c1
   <https://permalink.gmane.org/gmane.comp.lib.gnulib.bugs/15755>.*/
Packit Service 4684c1
#if GETTIMEOFDAY_CLOBBERS_LOCALTIME
Packit Service 4684c1
#undef localtime
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
#include <getpass.h>
Packit Service 4684c1
Packit Service 4684c1
#include <stdio.h>
Packit Service 4684c1
#include <stdlib.h>
Packit Service 4684c1
#include <string.h>
Packit Service 4684c1
#include <gnutls/gnutls.h>
Packit Service 4684c1
#include <gnutls/x509.h>
Packit Service 4684c1
#include <gnutls/crypto.h>
Packit Service 4684c1
#include <time.h>
Packit Service 4684c1
#include <common.h>
Packit Service 4684c1
#include <unistd.h>
Packit Service 4684c1
Packit Service 4684c1
#ifndef _WIN32
Packit Service 4684c1
# include <signal.h>
Packit Service 4684c1
#else
Packit Service 4684c1
#include <ws2tcpip.h>
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
#ifdef ENABLE_PKCS11
Packit Service 4684c1
#include <gnutls/pkcs11.h>
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
#define SU(x) (x!=NULL?x:"Unknown")
Packit Service 4684c1
Packit Service 4684c1
const char str_unknown[] = "(unknown)";
Packit Service 4684c1
Packit Service 4684c1
static FILE *logfile = NULL;
Packit Service 4684c1
/* Hex encodes the given data adding a semicolon between hex bytes.
Packit Service 4684c1
 */
Packit Service 4684c1
const char *raw_to_string(const unsigned char *raw, size_t raw_size)
Packit Service 4684c1
{
Packit Service 4684c1
	static char buf[1024];
Packit Service 4684c1
	size_t i;
Packit Service 4684c1
	if (raw_size == 0)
Packit Service 4684c1
		return "(empty)";
Packit Service 4684c1
Packit Service 4684c1
	if (raw_size * 3 + 1 >= sizeof(buf))
Packit Service 4684c1
		return "(too large)";
Packit Service 4684c1
Packit Service 4684c1
	for (i = 0; i < raw_size; i++) {
Packit Service 4684c1
		sprintf(&(buf[i * 3]), "%02X%s", raw[i],
Packit Service 4684c1
			(i == raw_size - 1) ? "" : ":");
Packit Service 4684c1
	}
Packit Service 4684c1
	buf[sizeof(buf) - 1] = '\0';
Packit Service 4684c1
Packit Service 4684c1
	return buf;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* Hex encodes the given data.
Packit Service 4684c1
 */
Packit Service 4684c1
const char *raw_to_hex(const unsigned char *raw, size_t raw_size)
Packit Service 4684c1
{
Packit Service 4684c1
	static char buf[1024];
Packit Service 4684c1
	size_t i;
Packit Service 4684c1
	if (raw_size == 0)
Packit Service 4684c1
		return "(empty)";
Packit Service 4684c1
Packit Service 4684c1
	if (raw_size * 2 + 1 >= sizeof(buf))
Packit Service 4684c1
		return "(too large)";
Packit Service 4684c1
Packit Service 4684c1
	for (i = 0; i < raw_size; i++) {
Packit Service 4684c1
		sprintf(&(buf[i * 2]), "%02x", raw[i]);
Packit Service 4684c1
	}
Packit Service 4684c1
	buf[sizeof(buf) - 1] = '\0';
Packit Service 4684c1
Packit Service 4684c1
	return buf;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
const char *raw_to_base64(const unsigned char *raw, size_t raw_size)
Packit Service 4684c1
{
Packit Service 4684c1
	static char buf[1024];
Packit Service 4684c1
	gnutls_datum_t data = {(unsigned char*)raw, raw_size};
Packit Service 4684c1
	size_t buf_size;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	if (raw_size == 0)
Packit Service 4684c1
		return "(empty)";
Packit Service 4684c1
Packit Service 4684c1
	buf_size = sizeof(buf);
Packit Service 4684c1
	ret = gnutls_pem_base64_encode(NULL, &data, buf, &buf_size);
Packit Service 4684c1
	if (ret < 0)
Packit Service 4684c1
		return "(error)";
Packit Service 4684c1
Packit Service 4684c1
	buf[sizeof(buf) - 1] = '\0';
Packit Service 4684c1
Packit Service 4684c1
	return buf;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
static void
Packit Service 4684c1
print_x509_info(gnutls_session_t session, FILE *out, int flag, int print_cert, int print_crt_status)
Packit Service 4684c1
{
Packit Service 4684c1
	gnutls_x509_crt_t crt;
Packit Service 4684c1
	const gnutls_datum_t *cert_list;
Packit Service 4684c1
	unsigned int cert_list_size = 0, j;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
Packit Service 4684c1
	if (cert_list_size == 0) {
Packit Service 4684c1
		if (print_crt_status)
Packit Service 4684c1
			fprintf(stderr, "No certificates found!\n");
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	log_msg(out, "- Certificate type: X.509\n");
Packit Service 4684c1
	log_msg(out, "- Got a certificate list of %d certificates.\n",
Packit Service 4684c1
	       cert_list_size);
Packit Service 4684c1
Packit Service 4684c1
	for (j = 0; j < cert_list_size; j++) {
Packit Service 4684c1
		gnutls_datum_t cinfo;
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_x509_crt_init(&crt;;
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			fprintf(stderr, "Memory error\n");
Packit Service 4684c1
			return;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		ret =
Packit Service 4684c1
		    gnutls_x509_crt_import(crt, &cert_list[j],
Packit Service 4684c1
					   GNUTLS_X509_FMT_DER);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			fprintf(stderr, "Decoding error: %s\n",
Packit Service 4684c1
				gnutls_strerror(ret));
Packit Service 4684c1
			return;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		log_msg(out, "- Certificate[%d] info:\n - ", j);
Packit Service 4684c1
		if (flag == GNUTLS_CRT_PRINT_COMPACT && j > 0)
Packit Service 4684c1
			flag = GNUTLS_CRT_PRINT_ONELINE;
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_x509_crt_print(crt, flag, &cinfo);
Packit Service 4684c1
		if (ret == 0) {
Packit Service 4684c1
			log_msg(out, "%s\n", cinfo.data);
Packit Service 4684c1
			gnutls_free(cinfo.data);
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		if (print_cert) {
Packit Service 4684c1
			gnutls_datum_t pem;
Packit Service 4684c1
Packit Service 4684c1
			ret =
Packit Service 4684c1
			    gnutls_x509_crt_export2(crt,
Packit Service 4684c1
						   GNUTLS_X509_FMT_PEM, &pem;;
Packit Service 4684c1
			if (ret < 0) {
Packit Service 4684c1
				fprintf(stderr, "Encoding error: %s\n",
Packit Service 4684c1
					gnutls_strerror(ret));
Packit Service 4684c1
				return;
Packit Service 4684c1
			}
Packit Service 4684c1
Packit Service 4684c1
			log_msg(out, "\n%s\n", (char*)pem.data);
Packit Service 4684c1
Packit Service 4684c1
			gnutls_free(pem.data);
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		gnutls_x509_crt_deinit(crt);
Packit Service 4684c1
	}
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
static void
Packit Service 4684c1
print_rawpk_info(gnutls_session_t session, FILE *out, int flag, int print_cert, int print_crt_status)
Packit Service 4684c1
{
Packit Service 4684c1
	gnutls_pcert_st pk_cert;
Packit Service 4684c1
	gnutls_pk_algorithm_t pk_algo;
Packit Service 4684c1
	const gnutls_datum_t *cert_list;
Packit Service 4684c1
	unsigned int cert_list_size = 0;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
Packit Service 4684c1
	if (cert_list_size == 0) {
Packit Service 4684c1
		if (print_crt_status)
Packit Service 4684c1
			fprintf(stderr, "No certificates found!\n");
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	log_msg(out, "- Certificate type: Raw Public Key\n");
Packit Service 4684c1
	log_msg(out, "- Got %d Raw public-key(s).\n",
Packit Service 4684c1
	       cert_list_size);
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_pcert_import_rawpk_raw(&pk_cert, cert_list, GNUTLS_X509_FMT_DER, 0, 0);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		fprintf(stderr, "Decoding error: %s\n",
Packit Service 4684c1
			gnutls_strerror(ret));
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	pk_algo = gnutls_pubkey_get_pk_algorithm(pk_cert.pubkey, NULL);
Packit Service 4684c1
Packit Service 4684c1
	log_msg(out, "- Raw pk info:\n");
Packit Service 4684c1
	log_msg(out, " - PK algo: %s\n", gnutls_pk_algorithm_get_name(pk_algo));
Packit Service 4684c1
Packit Service 4684c1
	if (print_cert) {
Packit Service 4684c1
		gnutls_datum_t pem;
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_pubkey_export2(pk_cert.pubkey, GNUTLS_X509_FMT_PEM, &pem;;
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			fprintf(stderr, "Encoding error: %s\n",
Packit Service 4684c1
				gnutls_strerror(ret));
Packit Service 4684c1
			return;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		log_msg(out, "\n%s\n", (char*)pem.data);
Packit Service 4684c1
Packit Service 4684c1
		gnutls_free(pem.data);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* returns false (0) if not verified, or true (1) otherwise 
Packit Service 4684c1
 */
Packit Service 4684c1
int cert_verify(gnutls_session_t session, const char *hostname, const char *purpose)
Packit Service 4684c1
{
Packit Service 4684c1
	int rc;
Packit Service 4684c1
	unsigned int status = 0;
Packit Service 4684c1
	gnutls_datum_t out;
Packit Service 4684c1
	int type;
Packit Service 4684c1
	gnutls_typed_vdata_st data[2];
Packit Service 4684c1
	unsigned elements = 0;
Packit Service 4684c1
Packit Service 4684c1
	memset(data, 0, sizeof(data));
Packit Service 4684c1
Packit Service 4684c1
	if (hostname) {
Packit Service 4684c1
		data[elements].type = GNUTLS_DT_DNS_HOSTNAME;
Packit Service 4684c1
		data[elements].data = (void*)hostname;
Packit Service 4684c1
		elements++;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (purpose) {
Packit Service 4684c1
		data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID;
Packit Service 4684c1
		data[elements].data = (void*)purpose;
Packit Service 4684c1
		elements++;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	rc = gnutls_certificate_verify_peers(session, data, elements, &status);
Packit Service 4684c1
	if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
Packit Service 4684c1
		log_msg(stdout, "- Peer did not send any certificate.\n");
Packit Service 4684c1
		return 0;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (rc < 0) {
Packit Service 4684c1
		log_msg(stdout, "- Could not verify certificate (err: %s)\n",
Packit Service 4684c1
		       gnutls_strerror(rc));
Packit Service 4684c1
		return 0;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	type = gnutls_certificate_type_get(session);
Packit Service 4684c1
	rc = gnutls_certificate_verification_status_print(status, type,
Packit Service 4684c1
							  &out, 0);
Packit Service 4684c1
	if (rc < 0) {
Packit Service 4684c1
		log_msg(stdout, "- Could not print verification flags (err: %s)\n",
Packit Service 4684c1
		       gnutls_strerror(rc));
Packit Service 4684c1
		return 0;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	log_msg(stdout, "- Status: %s\n", out.data);
Packit Service 4684c1
Packit Service 4684c1
	gnutls_free(out.data);
Packit Service 4684c1
Packit Service 4684c1
	if (status)
Packit Service 4684c1
		return 0;
Packit Service 4684c1
Packit Service 4684c1
	return 1;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
static void
Packit Service 4684c1
print_dh_info(gnutls_session_t session, const char *str, int print)
Packit Service 4684c1
{
Packit Service 4684c1
#if defined(ENABLE_DHE) || defined(ENABLE_ANON)
Packit Service 4684c1
	unsigned group;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	gnutls_datum_t raw_gen = { NULL, 0 };
Packit Service 4684c1
	gnutls_datum_t raw_prime = { NULL, 0 };
Packit Service 4684c1
	gnutls_dh_params_t dh_params = NULL;
Packit Service 4684c1
	unsigned char *params_data = NULL;
Packit Service 4684c1
	size_t params_data_size = 0;
Packit Service 4684c1
Packit Service 4684c1
	if (!print)
Packit Service 4684c1
		return;
Packit Service 4684c1
Packit Service 4684c1
	group = gnutls_group_get(session);
Packit Service 4684c1
	if (group != 0) {
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	log_msg(stdout, "- %sDiffie-Hellman parameters\n", str);
Packit Service 4684c1
	log_msg(stdout, " - Using prime: %d bits\n",
Packit Service 4684c1
	       gnutls_dh_get_prime_bits(session));
Packit Service 4684c1
	log_msg(stdout, " - Secret key: %d bits\n",
Packit Service 4684c1
	       gnutls_dh_get_secret_bits(session));
Packit Service 4684c1
	log_msg(stdout, " - Peer's public key: %d bits\n",
Packit Service 4684c1
	       gnutls_dh_get_peers_public_bits(session));
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_dh_get_group(session, &raw_gen, &raw_prime);
Packit Service 4684c1
	if (ret) {
Packit Service 4684c1
		fprintf(stderr, "gnutls_dh_get_group %d\n", ret);
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_dh_params_init(&dh_params);
Packit Service 4684c1
	if (ret) {
Packit Service 4684c1
		fprintf(stderr, "gnutls_dh_params_init %d\n", ret);
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    gnutls_dh_params_import_raw(dh_params, &raw_prime,
Packit Service 4684c1
						&raw_gen);
Packit Service 4684c1
	if (ret) {
Packit Service 4684c1
		fprintf(stderr, "gnutls_dh_params_import_raw %d\n",
Packit Service 4684c1
			ret);
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_dh_params_export_pkcs3(dh_params,
Packit Service 4684c1
					    GNUTLS_X509_FMT_PEM,
Packit Service 4684c1
					    params_data,
Packit Service 4684c1
					    &params_data_size);
Packit Service 4684c1
	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
Packit Service 4684c1
		fprintf(stderr,
Packit Service 4684c1
			"gnutls_dh_params_export_pkcs3 %d\n", ret);
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	params_data = gnutls_malloc(params_data_size);
Packit Service 4684c1
	if (!params_data) {
Packit Service 4684c1
		fprintf(stderr, "gnutls_malloc %d\n", ret);
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_dh_params_export_pkcs3(dh_params,
Packit Service 4684c1
					    GNUTLS_X509_FMT_PEM,
Packit Service 4684c1
					    params_data,
Packit Service 4684c1
					    &params_data_size);
Packit Service 4684c1
	if (ret) {
Packit Service 4684c1
		fprintf(stderr,
Packit Service 4684c1
			"gnutls_dh_params_export_pkcs3-2 %d\n",
Packit Service 4684c1
			ret);
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	log_msg(stdout, " - PKCS#3 format:\n\n%.*s\n",
Packit Service 4684c1
	       (int) params_data_size, params_data);
Packit Service 4684c1
Packit Service 4684c1
      out:
Packit Service 4684c1
	gnutls_free(params_data);
Packit Service 4684c1
	gnutls_free(raw_prime.data);
Packit Service 4684c1
	gnutls_free(raw_gen.data);
Packit Service 4684c1
	gnutls_dh_params_deinit(dh_params);
Packit Service 4684c1
#endif
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
static void print_ecdh_info(gnutls_session_t session, const char *str, int print)
Packit Service 4684c1
{
Packit Service 4684c1
	int curve;
Packit Service 4684c1
Packit Service 4684c1
	if (!print)
Packit Service 4684c1
		return;
Packit Service 4684c1
Packit Service 4684c1
	log_msg(stdout, "- %sEC Diffie-Hellman parameters\n", str);
Packit Service 4684c1
Packit Service 4684c1
	curve = gnutls_ecc_curve_get(session);
Packit Service 4684c1
Packit Service 4684c1
	log_msg(stdout, " - Using curve: %s\n", gnutls_ecc_curve_get_name(curve));
Packit Service 4684c1
	log_msg(stdout, " - Curve size: %d bits\n",
Packit Service 4684c1
	       gnutls_ecc_curve_get_size(curve) * 8);
Packit Service 4684c1
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
int print_info(gnutls_session_t session, int verbose, int flags)
Packit Service 4684c1
{
Packit Service 4684c1
	const char *tmp;
Packit Service 4684c1
	gnutls_credentials_type_t cred;
Packit Service 4684c1
	gnutls_kx_algorithm_t kx;
Packit Service 4684c1
	unsigned char session_id[33];
Packit Service 4684c1
	size_t session_id_size = sizeof(session_id);
Packit Service 4684c1
	gnutls_srtp_profile_t srtp_profile;
Packit Service 4684c1
	gnutls_datum_t p;
Packit Service 4684c1
	char *desc;
Packit Service 4684c1
	gnutls_protocol_t version;
Packit Service 4684c1
	int rc;
Packit Service 4684c1
Packit Service 4684c1
	desc = gnutls_session_get_desc(session);
Packit Service 4684c1
	log_msg(stdout, "- Description: %s\n", desc);
Packit Service 4684c1
	gnutls_free(desc);
Packit Service 4684c1
Packit Service 4684c1
	/* print session ID */
Packit Service 4684c1
	gnutls_session_get_id(session, session_id, &session_id_size);
Packit Service 4684c1
	if (session_id_size > 0) {
Packit Service 4684c1
		log_msg(stdout, "- Session ID: %s\n",
Packit Service 4684c1
		       raw_to_string(session_id, session_id_size));
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	/* print the key exchange's algorithm name
Packit Service 4684c1
	 */
Packit Service 4684c1
	kx = gnutls_kx_get(session);
Packit Service 4684c1
Packit Service 4684c1
	cred = gnutls_auth_get_type(session);
Packit Service 4684c1
	switch (cred) {
Packit Service 4684c1
#ifdef ENABLE_ANON
Packit Service 4684c1
	case GNUTLS_CRD_ANON:
Packit Service 4684c1
		if (kx == GNUTLS_KX_ANON_ECDH)
Packit Service 4684c1
			print_ecdh_info(session, "Anonymous ", verbose);
Packit Service 4684c1
		else
Packit Service 4684c1
			print_dh_info(session, "Anonymous ", verbose);
Packit Service 4684c1
		break;
Packit Service 4684c1
#endif
Packit Service 4684c1
#ifdef ENABLE_SRP
Packit Service 4684c1
	case GNUTLS_CRD_SRP:
Packit Service 4684c1
		/* This should be only called in server
Packit Service 4684c1
		 * side.
Packit Service 4684c1
		 */
Packit Service 4684c1
		if (gnutls_srp_server_get_username(session) != NULL)
Packit Service 4684c1
			log_msg(stdout, "- SRP authentication. Connected as '%s'\n",
Packit Service 4684c1
			       gnutls_srp_server_get_username(session));
Packit Service 4684c1
		break;
Packit Service 4684c1
#endif
Packit Service 4684c1
#ifdef ENABLE_PSK
Packit Service 4684c1
	case GNUTLS_CRD_PSK:
Packit Service 4684c1
		/* This returns NULL in server side.
Packit Service 4684c1
		 */
Packit Service 4684c1
		if (gnutls_psk_client_get_hint(session) != NULL)
Packit Service 4684c1
			log_msg(stdout, "- PSK authentication. PSK hint '%s'\n",
Packit Service 4684c1
			       gnutls_psk_client_get_hint(session));
Packit Service 4684c1
		/* This returns NULL in client side.
Packit Service 4684c1
		 */
Packit Service 4684c1
		if (gnutls_psk_server_get_username(session) != NULL)
Packit Service 4684c1
			log_msg(stdout, "- PSK authentication. Connected as '%s'\n",
Packit Service 4684c1
			       gnutls_psk_server_get_username(session));
Packit Service 4684c1
		if (kx == GNUTLS_KX_DHE_PSK)
Packit Service 4684c1
			print_dh_info(session, "Ephemeral ", verbose);
Packit Service 4684c1
		if (kx == GNUTLS_KX_ECDHE_PSK)
Packit Service 4684c1
			print_ecdh_info(session, "Ephemeral ", verbose);
Packit Service 4684c1
		break;
Packit Service 4684c1
#endif
Packit Service 4684c1
	case GNUTLS_CRD_IA:
Packit Service 4684c1
		log_msg(stdout, "- TLS/IA authentication\n");
Packit Service 4684c1
		break;
Packit Service 4684c1
	case GNUTLS_CRD_CERTIFICATE:
Packit Service 4684c1
		{
Packit Service 4684c1
			char dns[256];
Packit Service 4684c1
			size_t dns_size = sizeof(dns);
Packit Service 4684c1
			unsigned int type;
Packit Service 4684c1
Packit Service 4684c1
			/* This fails in client side */
Packit Service 4684c1
			if (gnutls_server_name_get
Packit Service 4684c1
			    (session, dns, &dns_size, &type, 0) == 0) {
Packit Service 4684c1
				log_msg(stdout, "- Given server name[%d]: %s\n",
Packit Service 4684c1
				       type, dns);
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		if ((flags & P_WAIT_FOR_CERT) && gnutls_certificate_get_ours(session) == 0)
Packit Service 4684c1
			log_msg(stdout, "- No certificate was sent to peer\n");
Packit Service 4684c1
Packit Service 4684c1
		if (flags& P_PRINT_CERT)
Packit Service 4684c1
			print_cert_info(session, verbose, (flags&P_PRINT_CERT));
Packit Service 4684c1
Packit Service 4684c1
		if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
Packit Service 4684c1
			print_dh_info(session, "Ephemeral ", verbose);
Packit Service 4684c1
		else if (kx == GNUTLS_KX_ECDHE_RSA
Packit Service 4684c1
			 || kx == GNUTLS_KX_ECDHE_ECDSA)
Packit Service 4684c1
			print_ecdh_info(session, "Ephemeral ", verbose);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
	if (verbose) {
Packit Service 4684c1
		version = gnutls_protocol_get_version(session);
Packit Service 4684c1
		tmp =
Packit Service 4684c1
		    SU(gnutls_protocol_get_name(version));
Packit Service 4684c1
		log_msg(stdout, "- Version: %s\n", tmp);
Packit Service 4684c1
Packit Service 4684c1
		if (version < GNUTLS_TLS1_3) {
Packit Service 4684c1
			tmp = SU(gnutls_kx_get_name(kx));
Packit Service 4684c1
			log_msg(stdout, "- Key Exchange: %s\n", tmp);
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		if (gnutls_sign_algorithm_get(session) != GNUTLS_SIGN_UNKNOWN) {
Packit Service 4684c1
			tmp =
Packit Service 4684c1
			    SU(gnutls_sign_get_name
Packit Service 4684c1
			       (gnutls_sign_algorithm_get(session)));
Packit Service 4684c1
			log_msg(stdout, "- Server Signature: %s\n", tmp);
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		if (gnutls_sign_algorithm_get_client(session) !=
Packit Service 4684c1
		    GNUTLS_SIGN_UNKNOWN) {
Packit Service 4684c1
			tmp =
Packit Service 4684c1
			    SU(gnutls_sign_get_name
Packit Service 4684c1
			       (gnutls_sign_algorithm_get_client(session)));
Packit Service 4684c1
			log_msg(stdout, "- Client Signature: %s\n", tmp);
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		tmp = SU(gnutls_cipher_get_name(gnutls_cipher_get(session)));
Packit Service 4684c1
		log_msg(stdout, "- Cipher: %s\n", tmp);
Packit Service 4684c1
Packit Service 4684c1
		tmp = SU(gnutls_mac_get_name(gnutls_mac_get(session)));
Packit Service 4684c1
		log_msg(stdout, "- MAC: %s\n", tmp);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	log_msg(stdout, "- Options:");
Packit Service 4684c1
	if (gnutls_session_ext_master_secret_status(session)!=0)
Packit Service 4684c1
		log_msg(stdout, " extended master secret,");
Packit Service 4684c1
	if (gnutls_safe_renegotiation_status(session)!=0)
Packit Service 4684c1
		log_msg(stdout, " safe renegotiation,");
Packit Service 4684c1
	if (gnutls_session_etm_status(session)!=0)
Packit Service 4684c1
		log_msg(stdout, " EtM,");
Packit Service 4684c1
#ifdef ENABLE_OCSP
Packit Service 4684c1
	if (gnutls_ocsp_status_request_is_checked(session, GNUTLS_OCSP_SR_IS_AVAIL)!=0) {
Packit Service 4684c1
		log_msg(stdout, " OCSP status request%s,", gnutls_ocsp_status_request_is_checked(session,0)!=0?"":"[ignored]");
Packit Service 4684c1
	}
Packit Service 4684c1
#endif
Packit Service 4684c1
	log_msg(stdout, "\n");
Packit Service 4684c1
Packit Service 4684c1
#ifdef ENABLE_DTLS_SRTP
Packit Service 4684c1
	rc = gnutls_srtp_get_selected_profile(session, &srtp_profile);
Packit Service 4684c1
	if (rc == 0)
Packit Service 4684c1
		log_msg(stdout, "- SRTP profile: %s\n",
Packit Service 4684c1
		       gnutls_srtp_get_profile_name(srtp_profile));
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
#ifdef ENABLE_ALPN
Packit Service 4684c1
	rc = gnutls_alpn_get_selected_protocol(session, &p);
Packit Service 4684c1
	if (rc == 0)
Packit Service 4684c1
		log_msg(stdout, "- Application protocol: %.*s\n", p.size, p.data);
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
	if (verbose) {
Packit Service 4684c1
		gnutls_datum_t cb;
Packit Service 4684c1
Packit Service 4684c1
		rc = gnutls_session_channel_binding(session,
Packit Service 4684c1
						    GNUTLS_CB_TLS_UNIQUE,
Packit Service 4684c1
						    &cb;;
Packit Service 4684c1
		if (rc)
Packit Service 4684c1
			fprintf(stderr, "Channel binding error: %s\n",
Packit Service 4684c1
				gnutls_strerror(rc));
Packit Service 4684c1
		else {
Packit Service 4684c1
			size_t i;
Packit Service 4684c1
Packit Service 4684c1
			log_msg(stdout, "- Channel binding 'tls-unique': ");
Packit Service 4684c1
			for (i = 0; i < cb.size; i++)
Packit Service 4684c1
				log_msg(stdout, "%02x", cb.data[i]);
Packit Service 4684c1
			log_msg(stdout, "\n");
Packit Service 4684c1
			gnutls_free(cb.data);
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	fflush(stdout);
Packit Service 4684c1
Packit Service 4684c1
	return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
void print_cert_info(gnutls_session_t session, int verbose, int print_cert)
Packit Service 4684c1
{
Packit Service 4684c1
	print_cert_info2(session, verbose, stdout, print_cert);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
void print_cert_info2(gnutls_session_t session, int verbose, FILE *out, int print_cert)
Packit Service 4684c1
{
Packit Service 4684c1
	int flag, print_crt_status = 0;
Packit Service 4684c1
Packit Service 4684c1
	if (verbose)
Packit Service 4684c1
		flag = GNUTLS_CRT_PRINT_FULL;
Packit Service 4684c1
	else
Packit Service 4684c1
		flag = GNUTLS_CRT_PRINT_COMPACT;
Packit Service 4684c1
Packit Service 4684c1
	if (gnutls_certificate_client_get_request_status(session) != 0) {
Packit Service 4684c1
		log_msg(stdout, "- Server has requested a certificate.\n");
Packit Service 4684c1
		print_crt_status = 1;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	switch (gnutls_certificate_type_get2(session, GNUTLS_CTYPE_PEERS)) {
Packit Service 4684c1
	case GNUTLS_CRT_X509:
Packit Service 4684c1
		print_x509_info(session, out, flag, print_cert, print_crt_status);
Packit Service 4684c1
		break;
Packit Service 4684c1
	case GNUTLS_CRT_RAWPK:
Packit Service 4684c1
		print_rawpk_info(session, out, flag, print_cert, print_crt_status);
Packit Service 4684c1
		break;
Packit Service 4684c1
	default:
Packit Service 4684c1
		break;
Packit Service 4684c1
	}
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
void print_list(const char *priorities, int verbose)
Packit Service 4684c1
{
Packit Service 4684c1
	size_t i;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	unsigned int idx;
Packit Service 4684c1
	const char *name;
Packit Service 4684c1
	const char *err;
Packit Service 4684c1
	unsigned char id[2];
Packit Service 4684c1
	gnutls_kx_algorithm_t kx;
Packit Service 4684c1
	gnutls_cipher_algorithm_t cipher;
Packit Service 4684c1
	gnutls_mac_algorithm_t mac;
Packit Service 4684c1
	gnutls_protocol_t version;
Packit Service 4684c1
	gnutls_priority_t pcache;
Packit Service 4684c1
	const unsigned int *list;
Packit Service 4684c1
Packit Service 4684c1
	if (priorities != NULL) {
Packit Service 4684c1
		log_msg(stdout, "Cipher suites for %s\n", priorities);
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_priority_init(&pcache, priorities, &err;;
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			if (ret == GNUTLS_E_INVALID_REQUEST)
Packit Service 4684c1
				fprintf(stderr, "Syntax error at: %s\n", err);
Packit Service 4684c1
			else
Packit Service 4684c1
				fprintf(stderr, "Error in priorities: %s\n", gnutls_strerror(ret));
Packit Service 4684c1
			exit(1);
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		for (i = 0;; i++) {
Packit Service 4684c1
			ret =
Packit Service 4684c1
			    gnutls_priority_get_cipher_suite_index(pcache,
Packit Service 4684c1
								   i,
Packit Service 4684c1
								   &idx);
Packit Service 4684c1
			if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
Packit Service 4684c1
				break;
Packit Service 4684c1
			if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE)
Packit Service 4684c1
				continue;
Packit Service 4684c1
Packit Service 4684c1
			name =
Packit Service 4684c1
			    gnutls_cipher_suite_info(idx, id, NULL, NULL,
Packit Service 4684c1
						     NULL, &version);
Packit Service 4684c1
Packit Service 4684c1
			if (name != NULL)
Packit Service 4684c1
				log_msg(stdout, "%-50s\t0x%02x, 0x%02x\t%s\n",
Packit Service 4684c1
				       name, (unsigned char) id[0],
Packit Service 4684c1
				       (unsigned char) id[1],
Packit Service 4684c1
				       gnutls_protocol_get_name(version));
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "\n");
Packit Service 4684c1
#if 0
Packit Service 4684c1
		{
Packit Service 4684c1
			ret =
Packit Service 4684c1
			    gnutls_priority_certificate_type_list2(pcache,
Packit Service 4684c1
								  &list,
Packit Service 4684c1
								  GNUTLS_CTYPE_CLIENT);
Packit Service 4684c1
Packit Service 4684c1
			log_msg(stdout, "Certificate types: ");
Packit Service 4684c1
			if (ret == 0)
Packit Service 4684c1
				log_msg(stdout, "none\n");
Packit Service 4684c1
			for (i = 0; i < (unsigned) ret; i++) {
Packit Service 4684c1
				log_msg(stdout, "CTYPE-%s",
Packit Service 4684c1
				       gnutls_certificate_type_get_name
Packit Service 4684c1
				       (list[i]));
Packit Service 4684c1
				if (i + 1 != (unsigned) ret)
Packit Service 4684c1
					log_msg(stdout, ", ");
Packit Service 4684c1
				else
Packit Service 4684c1
					log_msg(stdout, "\n");
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
		{
Packit Service 4684c1
			ret = gnutls_priority_protocol_list(pcache, &list);
Packit Service 4684c1
Packit Service 4684c1
			log_msg(stdout, "Protocols: ");
Packit Service 4684c1
			if (ret == 0)
Packit Service 4684c1
				log_msg(stdout, "none\n");
Packit Service 4684c1
			for (i = 0; i < (unsigned) ret; i++) {
Packit Service 4684c1
				log_msg(stdout, "VERS-%s",
Packit Service 4684c1
				       gnutls_protocol_get_name(list[i]));
Packit Service 4684c1
				if (i + 1 != (unsigned) ret)
Packit Service 4684c1
					log_msg(stdout, ", ");
Packit Service 4684c1
				else
Packit Service 4684c1
					log_msg(stdout, "\n");
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		{
Packit Service 4684c1
			ret = gnutls_priority_cipher_list(pcache, &list);
Packit Service 4684c1
Packit Service 4684c1
			log_msg(stdout, "Ciphers: ");
Packit Service 4684c1
			if (ret == 0)
Packit Service 4684c1
				log_msg(stdout, "none\n");
Packit Service 4684c1
			for (i = 0; i < (unsigned) ret; i++) {
Packit Service 4684c1
				log_msg(stdout, "%s",
Packit Service 4684c1
				       gnutls_cipher_get_name(list[i]));
Packit Service 4684c1
				if (i + 1 != (unsigned) ret)
Packit Service 4684c1
					log_msg(stdout, ", ");
Packit Service 4684c1
				else
Packit Service 4684c1
					log_msg(stdout, "\n");
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		{
Packit Service 4684c1
			ret = gnutls_priority_mac_list(pcache, &list);
Packit Service 4684c1
Packit Service 4684c1
			log_msg(stdout, "MACs: ");
Packit Service 4684c1
			if (ret == 0)
Packit Service 4684c1
				log_msg(stdout, "none\n");
Packit Service 4684c1
			for (i = 0; i < (unsigned) ret; i++) {
Packit Service 4684c1
				log_msg(stdout, "%s",
Packit Service 4684c1
				       gnutls_mac_get_name(list[i]));
Packit Service 4684c1
				if (i + 1 != (unsigned) ret)
Packit Service 4684c1
					log_msg(stdout, ", ");
Packit Service 4684c1
				else
Packit Service 4684c1
					log_msg(stdout, "\n");
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		{
Packit Service 4684c1
			ret = gnutls_priority_kx_list(pcache, &list);
Packit Service 4684c1
Packit Service 4684c1
			log_msg(stdout, "Key Exchange Algorithms: ");
Packit Service 4684c1
			if (ret == 0)
Packit Service 4684c1
				log_msg(stdout, "none\n");
Packit Service 4684c1
			for (i = 0; i < (unsigned) ret; i++) {
Packit Service 4684c1
				log_msg(stdout, "%s",
Packit Service 4684c1
				       gnutls_kx_get_name(list[i]));
Packit Service 4684c1
				if (i + 1 != (unsigned) ret)
Packit Service 4684c1
					log_msg(stdout, ", ");
Packit Service 4684c1
				else
Packit Service 4684c1
					log_msg(stdout, "\n");
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		{
Packit Service 4684c1
			ret =
Packit Service 4684c1
			    gnutls_priority_group_list(pcache, &list);
Packit Service 4684c1
Packit Service 4684c1
			log_msg(stdout, "Groups: ");
Packit Service 4684c1
			if (ret == 0)
Packit Service 4684c1
				log_msg(stdout, "none\n");
Packit Service 4684c1
			for (i = 0; i < (unsigned) ret; i++) {
Packit Service 4684c1
				log_msg(stdout, "GROUP-%s",
Packit Service 4684c1
				       gnutls_group_get_name(list[i]));
Packit Service 4684c1
				if (i + 1 != (unsigned) ret)
Packit Service 4684c1
					log_msg(stdout, ", ");
Packit Service 4684c1
				else
Packit Service 4684c1
					log_msg(stdout, "\n");
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		{
Packit Service 4684c1
			ret = gnutls_priority_sign_list(pcache, &list);
Packit Service 4684c1
Packit Service 4684c1
			log_msg(stdout, "PK-signatures: ");
Packit Service 4684c1
			if (ret == 0)
Packit Service 4684c1
				log_msg(stdout, "none\n");
Packit Service 4684c1
			for (i = 0; i < (unsigned) ret; i++) {
Packit Service 4684c1
				log_msg(stdout, "SIGN-%s",
Packit Service 4684c1
				       gnutls_sign_algorithm_get_name(list
Packit Service 4684c1
								      [i]));
Packit Service 4684c1
				if (i + 1 != (unsigned) ret)
Packit Service 4684c1
					log_msg(stdout, ", ");
Packit Service 4684c1
				else
Packit Service 4684c1
					log_msg(stdout, "\n");
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		gnutls_priority_deinit(pcache);
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	log_msg(stdout, "Cipher suites:\n");
Packit Service 4684c1
	for (i = 0; (name = gnutls_cipher_suite_info
Packit Service 4684c1
		     (i, id, &kx, &cipher, &mac, &version)); i++) {
Packit Service 4684c1
		log_msg(stdout, "%-50s\t0x%02x, 0x%02x\t%s\n",
Packit Service 4684c1
		       name,
Packit Service 4684c1
		       (unsigned char) id[0], (unsigned char) id[1],
Packit Service 4684c1
		       gnutls_protocol_get_name(version));
Packit Service 4684c1
		if (verbose)
Packit Service 4684c1
			log_msg
Packit Service 4684c1
			    (stdout, "\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
Packit Service 4684c1
			     gnutls_kx_get_name(kx),
Packit Service 4684c1
			     gnutls_cipher_get_name(cipher),
Packit Service 4684c1
			     gnutls_mac_get_name(mac));
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	log_msg(stdout, "\n");
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_certificate_type_t *p =
Packit Service 4684c1
		    gnutls_certificate_type_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "Certificate types: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "CTYPE-%s",
Packit Service 4684c1
			       gnutls_certificate_type_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_protocol_t *p = gnutls_protocol_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "Protocols: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "VERS-%s", gnutls_protocol_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_cipher_algorithm_t *p = gnutls_cipher_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "Ciphers: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "%s", gnutls_cipher_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_mac_algorithm_t *p = gnutls_mac_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "MACs: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "%s", gnutls_mac_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_digest_algorithm_t *p = gnutls_digest_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "Digests: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "%s", gnutls_digest_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_kx_algorithm_t *p = gnutls_kx_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "Key exchange algorithms: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "%s", gnutls_kx_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_compression_method_t *p =
Packit Service 4684c1
		    gnutls_compression_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "Compression: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "COMP-%s", gnutls_compression_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_group_t *p = gnutls_group_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "Groups: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "GROUP-%s", gnutls_group_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_pk_algorithm_t *p = gnutls_pk_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "Public Key Systems: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "%s", gnutls_pk_algorithm_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	{
Packit Service 4684c1
		const gnutls_sign_algorithm_t *p = gnutls_sign_list();
Packit Service 4684c1
Packit Service 4684c1
		log_msg(stdout, "PK-signatures: ");
Packit Service 4684c1
		for (; *p; p++) {
Packit Service 4684c1
			log_msg(stdout, "SIGN-%s",
Packit Service 4684c1
			       gnutls_sign_algorithm_get_name(*p));
Packit Service 4684c1
			if (*(p + 1))
Packit Service 4684c1
				log_msg(stdout, ", ");
Packit Service 4684c1
			else
Packit Service 4684c1
				log_msg(stdout, "\n");
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
void
Packit Service 4684c1
print_key_material(gnutls_session_t session, const char *label, size_t size)
Packit Service 4684c1
{
Packit Service 4684c1
	gnutls_datum_t bin = { NULL, 0 }, hex = { NULL, 0 };
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	bin.data = gnutls_malloc(size);
Packit Service 4684c1
	if (!bin.data) {
Packit Service 4684c1
		fprintf(stderr, "Error in gnutls_malloc: %s\n",
Packit Service 4684c1
			gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	bin.size = size;
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_prf_rfc5705(session, strlen(label), label,
Packit Service 4684c1
				 0, NULL, size, (char *)bin.data);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		fprintf(stderr, "Error in gnutls_prf_rfc5705: %s\n",
Packit Service 4684c1
			gnutls_strerror(ret));
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_hex_encode2(&bin, &hex;;
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		fprintf(stderr, "Error in hex encoding: %s\n",
Packit Service 4684c1
			gnutls_strerror(ret));
Packit Service 4684c1
		goto out;
Packit Service 4684c1
	}
Packit Service 4684c1
	log_msg(stdout, "- Key material: %s\n", hex.data);
Packit Service 4684c1
	fflush(stdout);
Packit Service 4684c1
Packit Service 4684c1
 out:
Packit Service 4684c1
	gnutls_free(bin.data);
Packit Service 4684c1
	gnutls_free(hex.data);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
int check_command(gnutls_session_t session, const char *str, unsigned no_cli_cert)
Packit Service 4684c1
{
Packit Service 4684c1
	size_t len = strnlen(str, 128);
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	fprintf(stderr, "*** Processing %u bytes command: %s\n", (unsigned)len,
Packit Service 4684c1
		str);
Packit Service 4684c1
	if (len > 2 && str[0] == str[1] && str[0] == '*') {
Packit Service 4684c1
		if (strncmp
Packit Service 4684c1
		    (str, "**REHANDSHAKE**",
Packit Service 4684c1
		     sizeof("**REHANDSHAKE**") - 1) == 0) {
Packit Service 4684c1
			fprintf(stderr,
Packit Service 4684c1
				"*** Sending rehandshake request\n");
Packit Service 4684c1
			gnutls_rehandshake(session);
Packit Service 4684c1
			return 1;
Packit Service 4684c1
		} else if (strncmp
Packit Service 4684c1
		    (str, "**REAUTH**",
Packit Service 4684c1
		     sizeof("**REAUTH**") - 1) == 0) {
Packit Service 4684c1
			/* in case we have a re-auth cmd prepare for it */
Packit Service 4684c1
			if (no_cli_cert)
Packit Service 4684c1
				gnutls_certificate_server_set_request(session, GNUTLS_CERT_REQUIRE);
Packit Service 4684c1
Packit Service 4684c1
			fprintf(stderr,
Packit Service 4684c1
				"*** Sending re-auth request\n");
Packit Service 4684c1
			do {
Packit Service 4684c1
				ret = gnutls_reauth(session, 0);
Packit Service 4684c1
			} while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
Packit Service 4684c1
			if (ret < 0) {
Packit Service 4684c1
				fprintf(stderr, "reauth: %s\n",
Packit Service 4684c1
					gnutls_strerror(ret));
Packit Service 4684c1
				return ret;
Packit Service 4684c1
			}
Packit Service 4684c1
			return 1;
Packit Service 4684c1
		} else
Packit Service 4684c1
		    if (strncmp
Packit Service 4684c1
			(str, "**HEARTBEAT**",
Packit Service 4684c1
			 sizeof("**HEARTBEAT**") - 1) == 0) {
Packit Service 4684c1
			ret =
Packit Service 4684c1
			    gnutls_heartbeat_ping(session, 300, 5,
Packit Service 4684c1
						  GNUTLS_HEARTBEAT_WAIT);
Packit Service 4684c1
			if (ret < 0) {
Packit Service 4684c1
				if (ret == GNUTLS_E_INVALID_REQUEST) {
Packit Service 4684c1
					fprintf(stderr,
Packit Service 4684c1
						"No heartbeat in this session\n");
Packit Service 4684c1
				} else {
Packit Service 4684c1
					fprintf(stderr, "ping: %s\n",
Packit Service 4684c1
						gnutls_strerror(ret));
Packit Service 4684c1
					return ret;
Packit Service 4684c1
				}
Packit Service 4684c1
			}
Packit Service 4684c1
			return 2;
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
	return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* error is indicated by returning an empty string */
Packit Service 4684c1
void getpass_copy(char *pass, size_t max_pass_size, const char *prompt)
Packit Service 4684c1
{
Packit Service 4684c1
	char *tmp;
Packit Service 4684c1
	size_t len;
Packit Service 4684c1
Packit Service 4684c1
	tmp = getpass(prompt);
Packit Service 4684c1
	if (tmp == NULL) {
Packit Service 4684c1
		pass[0] = 0;
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	len = strlen(tmp);
Packit Service 4684c1
	if (len >= max_pass_size) {
Packit Service 4684c1
		gnutls_memset(tmp, 0, len);
Packit Service 4684c1
		pass[0] = 0;
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	strcpy(pass, tmp);
Packit Service 4684c1
	gnutls_memset(tmp, 0, len);
Packit Service 4684c1
Packit Service 4684c1
	return;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* error is indicated by returning an empty string */
Packit Service 4684c1
void getenv_copy(char *str, size_t max_str_size, const char *envvar)
Packit Service 4684c1
{
Packit Service 4684c1
	char *tmp;
Packit Service 4684c1
	size_t len;
Packit Service 4684c1
Packit Service 4684c1
	tmp = getenv(envvar);
Packit Service 4684c1
	if (tmp == NULL) {
Packit Service 4684c1
		str[0] = 0;
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	len = strlen(tmp);
Packit Service 4684c1
	if (len >= max_str_size) {
Packit Service 4684c1
		str[0] = 0;
Packit Service 4684c1
		return;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	strcpy(str, tmp);
Packit Service 4684c1
Packit Service 4684c1
	return;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#define MIN(x,y) ((x)<(y))?(x):(y)
Packit Service 4684c1
#define MAX_CACHE_TRIES 5
Packit Service 4684c1
int
Packit Service 4684c1
pin_callback(void *user, int attempt, const char *token_url,
Packit Service 4684c1
	     const char *token_label, unsigned int flags, char *pin,
Packit Service 4684c1
	     size_t pin_max)
Packit Service 4684c1
{
Packit Service 4684c1
	char password[MAX_PIN_LEN] = "";
Packit Service 4684c1
	common_info_st *info = user;
Packit Service 4684c1
	const char *desc;
Packit Service 4684c1
	int cache = MAX_CACHE_TRIES;
Packit Service 4684c1
	unsigned len;
Packit Service 4684c1
/* allow caching of PIN */
Packit Service 4684c1
	static char *cached_url = NULL;
Packit Service 4684c1
	static char cached_pin[MAX_PIN_LEN] = "";
Packit Service 4684c1
	const char *env;
Packit Service 4684c1
Packit Service 4684c1
	if (flags & GNUTLS_PIN_SO) {
Packit Service 4684c1
		env = "GNUTLS_SO_PIN";
Packit Service 4684c1
		desc = "security officer";
Packit Service 4684c1
		if (info && info->so_pin)
Packit Service 4684c1
			snprintf(password, sizeof(password), "%s", info->so_pin);
Packit Service 4684c1
	} else {
Packit Service 4684c1
		env = "GNUTLS_PIN";
Packit Service 4684c1
		desc = "user";
Packit Service 4684c1
		if (info && info->pin)
Packit Service 4684c1
			snprintf(password, sizeof(password), "%s", info->pin);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (flags & GNUTLS_PIN_FINAL_TRY) {
Packit Service 4684c1
		cache = 0;
Packit Service 4684c1
		log_msg(stdout, "*** This is the final try before locking!\n");
Packit Service 4684c1
	}
Packit Service 4684c1
	if (flags & GNUTLS_PIN_COUNT_LOW) {
Packit Service 4684c1
		cache = 0;
Packit Service 4684c1
		log_msg(stdout, "*** Only few tries left before locking!\n");
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (flags & GNUTLS_PIN_WRONG) {
Packit Service 4684c1
		cache = 0;
Packit Service 4684c1
		log_msg(stdout, "*** Wrong PIN has been provided!\n");
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (cache > 0 && cached_url != NULL) {
Packit Service 4684c1
		if (token_url != NULL
Packit Service 4684c1
		    && strcmp(cached_url, token_url) == 0) {
Packit Service 4684c1
			if (strlen(cached_pin) >= pin_max) {
Packit Service 4684c1
				fprintf(stderr, "Too long PIN given\n");
Packit Service 4684c1
				exit(1);
Packit Service 4684c1
			}
Packit Service 4684c1
Packit Service 4684c1
			if (info && info->verbose) {
Packit Service 4684c1
				fprintf(stderr,
Packit Service 4684c1
					"Re-using cached PIN for token '%s'\n",
Packit Service 4684c1
					token_label);
Packit Service 4684c1
			}
Packit Service 4684c1
			strcpy(pin, cached_pin);
Packit Service 4684c1
			cache--;
Packit Service 4684c1
			return 0;
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (password[0] == 0) {
Packit Service 4684c1
		getenv_copy(password, sizeof(password), env);
Packit Service 4684c1
		if (password[0] == 0) /* compatibility */
Packit Service 4684c1
			getenv_copy(password, sizeof(password), "GNUTLS_PIN");
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (password[0] == 0 && (info == NULL || info->batch == 0 || info->ask_pass != 0)) {
Packit Service 4684c1
		if (token_label && token_label[0] != 0) {
Packit Service 4684c1
			fprintf(stderr, "Token '%s' with URL '%s' ", token_label, token_url);
Packit Service 4684c1
			fprintf(stderr, "requires %s PIN\n", desc);
Packit Service 4684c1
			getpass_copy(password, sizeof(password), "Enter PIN: ");
Packit Service 4684c1
		} else {
Packit Service 4684c1
			getpass_copy(password, sizeof(password), "Enter password: ");
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
	} else {
Packit Service 4684c1
		if (flags & GNUTLS_PIN_WRONG) {
Packit Service 4684c1
			if (token_label && token_label[0] != 0) {
Packit Service 4684c1
				fprintf(stderr, "Token '%s' with URL '%s' ", token_label, token_url);
Packit Service 4684c1
				fprintf(stderr, "requires %s PIN\n", desc);
Packit Service 4684c1
			}
Packit Service 4684c1
			fprintf(stderr, "Cannot continue with a wrong password in the environment.\n");
Packit Service 4684c1
			exit(1);
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (password[0] == 0 || password[0] == '\n') {
Packit Service 4684c1
		fprintf(stderr, "No PIN given.\n");
Packit Service 4684c1
		if (info != NULL && info->batch != 0) {
Packit Service 4684c1
			fprintf(stderr, "note: when operating in batch mode, set the GNUTLS_PIN or GNUTLS_SO_PIN environment variables\n");
Packit Service 4684c1
		}
Packit Service 4684c1
		exit(1);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	len = MIN(pin_max - 1, strlen(password));
Packit Service 4684c1
	memcpy(pin, password, len);
Packit Service 4684c1
	pin[len] = 0;
Packit Service 4684c1
Packit Service 4684c1
	/* cache */
Packit Service 4684c1
	if (len < sizeof(cached_pin)) {
Packit Service 4684c1
		memcpy(cached_pin, pin, len);
Packit Service 4684c1
		cached_pin[len] = 0;
Packit Service 4684c1
	} else
Packit Service 4684c1
		cached_pin[0] = 0;
Packit Service 4684c1
Packit Service 4684c1
	free(cached_url);
Packit Service 4684c1
	if (token_url)
Packit Service 4684c1
		cached_url = strdup(token_url);
Packit Service 4684c1
	else
Packit Service 4684c1
		cached_url = NULL;
Packit Service 4684c1
Packit Service 4684c1
	return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#ifdef ENABLE_PKCS11
Packit Service 4684c1
Packit Service 4684c1
static int
Packit Service 4684c1
token_callback(void *user, const char *label, const unsigned retry)
Packit Service 4684c1
{
Packit Service 4684c1
	char buf[32];
Packit Service 4684c1
	common_info_st *info = user;
Packit Service 4684c1
Packit Service 4684c1
	if (retry > 0 || (info != NULL && info->batch != 0)) {
Packit Service 4684c1
		fprintf(stderr, "Could not find token %s\n", label);
Packit Service 4684c1
		return -1;
Packit Service 4684c1
	}
Packit Service 4684c1
	log_msg(stdout, "Please insert token '%s' in slot and press enter\n",
Packit Service 4684c1
	       label);
Packit Service 4684c1
	if (fgets(buf, sizeof(buf), stdin) == NULL) {
Packit Service 4684c1
		fprintf(stderr, "error reading input\n");
Packit Service 4684c1
		return -1;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
void pkcs11_common(common_info_st *c)
Packit Service 4684c1
{
Packit Service 4684c1
Packit Service 4684c1
	gnutls_pkcs11_set_pin_function(pin_callback, c);
Packit Service 4684c1
	gnutls_pkcs11_set_token_function(token_callback, c);
Packit Service 4684c1
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
void sockets_init(void)
Packit Service 4684c1
{
Packit Service 4684c1
#ifdef _WIN32
Packit Service 4684c1
	WORD wVersionRequested;
Packit Service 4684c1
	WSADATA wsaData;
Packit Service 4684c1
Packit Service 4684c1
	wVersionRequested = MAKEWORD(1, 1);
Packit Service 4684c1
	if (WSAStartup(wVersionRequested, &wsaData) != 0) {
Packit Service 4684c1
		perror("WSA_STARTUP_ERROR");
Packit Service 4684c1
	}
Packit Service 4684c1
#else
Packit Service 4684c1
	signal(SIGPIPE, SIG_IGN);
Packit Service 4684c1
#endif
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
int log_msg(FILE *file, const char *message, ...)
Packit Service 4684c1
{
Packit Service 4684c1
	va_list args;
Packit Service 4684c1
	int rv;
Packit Service 4684c1
Packit Service 4684c1
	va_start(args, message);
Packit Service 4684c1
Packit Service 4684c1
	rv = vfprintf(logfile ? logfile : file, message, args);
Packit Service 4684c1
Packit Service 4684c1
	va_end(args);
Packit Service 4684c1
Packit Service 4684c1
	return rv;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
void log_set(FILE *file)
Packit Service 4684c1
{
Packit Service 4684c1
	logfile = file;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* This is very similar to ctime() but it does not force a newline.
Packit Service 4684c1
 */
Packit Service 4684c1
char *simple_ctime(const time_t *t, char out[SIMPLE_CTIME_BUF_SIZE])
Packit Service 4684c1
{
Packit Service 4684c1
	struct tm tm;
Packit Service 4684c1
Packit Service 4684c1
	if (localtime_r(t, &tm) == NULL)
Packit Service 4684c1
		goto error;
Packit Service 4684c1
Packit Service 4684c1
	if (!strftime(out, SIMPLE_CTIME_BUF_SIZE, "%c", &tm))
Packit Service 4684c1
		goto error;
Packit Service 4684c1
Packit Service 4684c1
	return out;
Packit Service 4684c1
Packit Service 4684c1
 error:
Packit Service 4684c1
	snprintf(out, SIMPLE_CTIME_BUF_SIZE, "[error]");
Packit Service 4684c1
	return out;
Packit Service 4684c1
}