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