Example #1
0
File: ssl.c Project: ezc/elinks
unsigned char *
get_ssl_connection_cipher(struct socket *socket)
{
	ssl_t *ssl = socket->ssl;
	struct string str;

	if (!init_string(&str)) return NULL;

#ifdef USE_OPENSSL
	add_format_to_string(&str, "%ld-bit %s %s",
		SSL_get_cipher_bits(ssl, NULL),
		SSL_get_cipher_version(ssl),
		SSL_get_cipher_name(ssl));
#elif defined(CONFIG_GNUTLS)
	/* XXX: How to get other relevant parameters? */
	add_format_to_string(&str, "%s - %s - %s - %s - %s (compr: %s)",
		gnutls_protocol_get_name(gnutls_protocol_get_version(*ssl)),
		gnutls_kx_get_name(gnutls_kx_get(*ssl)),
		gnutls_cipher_get_name(gnutls_cipher_get(*ssl)),
		gnutls_mac_get_name(gnutls_mac_get(*ssl)),
		gnutls_certificate_type_get_name(gnutls_certificate_type_get(*ssl)),
		gnutls_compression_get_name(gnutls_compression_get(*ssl)));
#endif

	return str.source;
}
Example #2
0
bool
ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
{
#ifdef HAVE_LIBSSL
	char *nl;
	SSL *ssl = c->ssl_state.ssl;

	if (!ssl)
		return false;
	*buf = 0;
	SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, len);
	nl = strchr(buf, '\n');
	if (nl)
		*nl = 0;
	return true;
#endif
#ifdef HAVE_LIBGNUTLS
	if (Conn_OPTION_ISSET(c, CONN_SSL)) {
		const char *name_cipher, *name_mac, *name_proto, *name_keyexchange;
		unsigned keysize;

		gnutls_session_t sess = c->ssl_state.gnutls_session;
		gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
		name_cipher = gnutls_cipher_get_name(cipher);
		name_mac = gnutls_mac_get_name(gnutls_mac_get(sess));
		keysize = gnutls_cipher_get_key_size(cipher) * 8;
		name_proto = gnutls_protocol_get_name(gnutls_protocol_get_version(sess));
		name_keyexchange = gnutls_kx_get_name(gnutls_kx_get(sess));

		return snprintf(buf, len, "%s-%s%15s Kx=%s      Enc=%s(%u) Mac=%s",
			name_cipher, name_mac, name_proto, name_keyexchange, name_cipher, keysize, name_mac) > 0;
	}
	return false;
#endif
}
static void mac_bench(int algo, int size)
{
	void *_key;
	int blocksize = gnutls_hmac_get_len(algo);
	int step = size * 1024;
	struct benchmark_st st;

	_key = malloc(blocksize);
	if (_key == NULL)
		return;
	memset(_key, 0xf0, blocksize);

	printf("%16s ", gnutls_mac_get_name(algo));
	fflush(stdout);

	start_benchmark(&st);

	do {
		gnutls_hmac_fast(algo, _key, blocksize, data, step, _key);
		st.size += step;
	}
	while (benchmark_must_finish == 0);

	stop_benchmark(&st, NULL, 1);

	free(_key);
}
Example #4
0
static void
tls_print_session_info(const host_addr_t addr, uint16 port,
                       gnutls_session session, bool incoming)
{
    const char *proto, *cert, *kx, *ciph, *mac, *comp;

    g_return_if_fail(session);

    proto = gnutls_protocol_get_name(gnutls_protocol_get_version(session));
    cert = gnutls_certificate_type_get_name(
               gnutls_certificate_type_get(session));
    kx = gnutls_kx_get_name(gnutls_kx_get(session));
    comp = gnutls_compression_get_name(gnutls_compression_get(session));
    ciph = gnutls_cipher_get_name(gnutls_cipher_get(session));
    mac = gnutls_mac_get_name(gnutls_mac_get (session));

    g_debug(
        "TLS session info (%s):\n"
        "    Host:         %s\n"
        "    Protocol:     %s\n"
        "    Certificate:  %s\n"
        "    Key Exchange: %s\n"
        "    Cipher:       %s\n"
        "    MAC:          %s\n"
        "    Compression:  %s",
        incoming ? "incoming" : "outgoing",
        host_addr_port_to_string(addr, port),
        NULL_STRING(proto),
        NULL_STRING(cert),
        NULL_STRING(kx),
        NULL_STRING(ciph),
        NULL_STRING(mac),
        NULL_STRING(comp)
    );
}
char *
SSL_CIPHER_description (SSL_CIPHER * cipher, char *buf, int size)
{
  char *tmpbuf;
  int tmpsize;
  int local_alloc;

  if (buf)
    {
      tmpbuf = buf;
      tmpsize = size;
      local_alloc = 0;
    }
  else
    {
      tmpbuf = (char *) malloc (128);
      tmpsize = 128;
      local_alloc = 1;
    }

  if (snprintf (tmpbuf, tmpsize, "%s %s %s %s",
                gnutls_protocol_get_name (cipher->version),
                gnutls_kx_get_name (cipher->kx),
                gnutls_cipher_get_name (cipher->cipher),
                gnutls_mac_get_name (cipher->mac)) == -1)
    {
      if (local_alloc)
        free (tmpbuf);
      return (char *) "Buffer too small";
    }

  return tmpbuf;
}
Example #6
0
const char *dtls_gnutls_get_cipher(struct conn *conn, char *dst)
{
	struct dtls_gnutls_data * d;
	const char *comp, *cipher, *mac, *proto, *kxname, *auth;
	gnutls_kx_algorithm_t kx;
	gnutls_credentials_type_t cred;
	
	if (!conn->dtls_data){
		sprintf(dst, "%s","None");
		return dst;
	}

	d = (struct dtls_gnutls_data*)conn->dtls_data;
	if ( !d->session ){
		sprintf(dst, "%s","None");
		return dst;
	}
	kx = gnutls_kx_get(d->session);
	kxname = gnutls_kx_get_name(kx);

	cred = gnutls_auth_get_type(d->session);

	proto = gnutls_protocol_get_name(gnutls_protocol_get_version(d->session));
	comp = gnutls_compression_get_name(gnutls_compression_get(d->session));
	cipher = gnutls_cipher_get_name(gnutls_cipher_get(d->session));
	mac = gnutls_mac_get_name(gnutls_mac_get(d->session));
	sprintf(dst,"cipher: %s/%s/%s/%s/%s",proto,kxname,cipher,mac,comp);

	return dst;
}
Example #7
0
wxString CTlsSocket::GetMacName()
{
	const char* mac = gnutls_mac_get_name(gnutls_mac_get(m_session));
	if (mac && *mac)
		return wxString(mac, wxConvUTF8);
	else
		return _T("unknown");
}
Example #8
0
/* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
 */
static int
_gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
                                    gnutls_pcert_st* cert, gnutls_privkey_t pkey,
                                    gnutls_datum_t * signature)
{
  gnutls_datum_t dconcat;
  int ret;
  opaque concat[MAX_SIG_SIZE];
  digest_hd_st td;
  gnutls_sign_algorithm_t sign_algo;
  gnutls_digest_algorithm_t hash_algo;
  digest_hd_st *handshake_td;

  sign_algo =
    _gnutls_session_get_sign_algo (session, cert);
  if (sign_algo == GNUTLS_SIGN_UNKNOWN)
    {
      gnutls_assert ();
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);

  _gnutls_debug_log ("sign handshake cert vrfy: picked %s with %s\n",
                    gnutls_sign_algorithm_get_name (sign_algo),
                    gnutls_mac_get_name (hash_algo));

  if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha1.algorithm)
    handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
  else if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha256.algorithm)
    handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
  else
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); /* too bad we only support SHA1 and SHA256 */

  ret = _gnutls_hash_copy (&td, handshake_td);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash_deinit (&td, concat);

  dconcat.data = concat;
  dconcat.size = _gnutls_hash_get_algo_len (hash_algo);

  ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return sign_algo;
}
Example #9
0
/* This function will log some details of the given session. */
static void
logtlsinfo (gnutls_session_t session)
{
  gnutls_credentials_type_t cred;
  const char *protocol =
    gnutls_protocol_get_name (gnutls_protocol_get_version (session));
  gnutls_kx_algorithm_t kx = gnutls_kx_get (session);
  const char *keyexchange = gnutls_kx_get_name (kx);
  const char *certtype =
    gnutls_certificate_type_get_name (gnutls_certificate_type_get (session));
  const char *cipher = gnutls_cipher_get_name (gnutls_cipher_get (session));
  const char *mac = gnutls_mac_get_name (gnutls_mac_get (session));
  const char *compression =
    gnutls_compression_get_name (gnutls_compression_get (session));
  int resumedp = gnutls_session_is_resumed (session);

  /* This message can arguably belong to LOG_AUTH.  */
  syslog (LOG_INFO, "TLS handshake negotiated protocol `%s', "
	  "key exchange `%s', certficate type `%s', cipher `%s', "
	  "mac `%s', compression `%s', %s",
	  protocol ? protocol : "N/A",
	  keyexchange ? keyexchange : "N/A",
	  certtype ? certtype : "N/A",
	  cipher ? cipher : "N/A",
	  mac ? mac : "N/A", compression ? compression : "N/A",
	  resumedp ? "resumed session" : "session not resumed");

  cred = gnutls_auth_get_type (session);
  switch (cred)
    {
    case GNUTLS_CRD_ANON:
      syslog (LOG_INFO | LOG_DAEMON,
	      "TLS anonymous authentication with %d bit Diffie-Hellman",
	      gnutls_dh_get_prime_bits (session));
      break;

    case GNUTLS_CRD_CERTIFICATE:
      if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
	syslog (LOG_INFO | LOG_DAEMON,
		"TLS certificate authentication with %d bits "
		"ephemeral Diffie-Hellman",
		gnutls_dh_get_prime_bits (session));
      logcertinfo (session);
      break;

    case GNUTLS_CRD_SRP:
    case GNUTLS_CRD_PSK:
    case GNUTLS_CRD_IA:
    default:
      syslog (LOG_ERR | LOG_DAEMON, "Unknown TLS authentication (%d)", cred);
      break;
    }
}
Example #10
0
const char *
rb_ssl_get_cipher(rb_fde_t *F)
{
	static char buf[1024];

	snprintf(buf, sizeof(buf), "%s-%s-%s-%s",
		gnutls_protocol_get_name(gnutls_protocol_get_version(SSL_P(F))),
		gnutls_kx_get_name(gnutls_kx_get(SSL_P(F))),
		gnutls_cipher_get_name(gnutls_cipher_get(SSL_P(F))),
		gnutls_mac_get_name(gnutls_mac_get(SSL_P(F))));

	return buf;
}
Example #11
0
static void
mac_bench (int algo, int size)
{
  void *_key;
  struct timespec start, stop;
  double secs;
  double data_size = 0;
  double ddata, dspeed;
  int blocksize = gnutls_hmac_get_len (algo);
  char metric[16];

  _key = malloc (blocksize);
  if (_key == NULL)
    return;
  memset (_key, 0xf0, blocksize);

  printf ("Checking %s (%dkb payload)... ", gnutls_mac_get_name (algo), size);
  fflush (stdout);

  must_finish = 0;
  alarm (5);

  gettime (&start);

  do
    {
      gnutls_hmac_fast (algo, _key, blocksize, data, size * 1024, _key);
      data_size += size * 1024;
    }
  while (must_finish == 0);

  gettime (&stop);

  secs =
    (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) -
     (start.tv_sec * 1000 + start.tv_nsec / (1000 * 1000)));
  secs /= 1000;

  value2human (data_size, secs, &ddata, &dspeed, metric);

  printf ("Hashed %.2f %s in %.2f secs: ", ddata, metric, secs);
  printf ("%.2f %s/sec\n", dspeed, metric);

  free (_key);
}
Example #12
0
static void
ConnSSL_LogCertInfo( CONNECTION *c )
{
#ifdef HAVE_LIBSSL
	SSL *ssl = c->ssl_state.ssl;

	assert(ssl);

	Log(LOG_INFO, "Connection %d: initialized %s using cipher %s.",
		c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl));
#endif
#ifdef HAVE_LIBGNUTLS
	gnutls_session_t sess = c->ssl_state.gnutls_session;
	gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);

	Log(LOG_INFO, "Connection %d: initialized %s using cipher %s-%s.",
	    c->sock,
	    gnutls_protocol_get_name(gnutls_protocol_get_version(sess)),
	    gnutls_cipher_get_name(cipher),
	    gnutls_mac_get_name(gnutls_mac_get(sess)));
#endif
}
Example #13
0
  void GnuTLSClientAnon::getCertInfo()
  {
    m_certInfo.status = CertOk;

    const char* info;
    info = gnutls_compression_get_name( gnutls_compression_get( *m_session ) );
    if( info )
      m_certInfo.compression = info;

    info = gnutls_mac_get_name( gnutls_mac_get( *m_session ) );
    if( info )
      m_certInfo.mac = info;

    info = gnutls_cipher_get_name( gnutls_cipher_get( *m_session ) );
    if( info )
      m_certInfo.cipher = info;

    info = gnutls_protocol_get_name( gnutls_protocol_get_version( *m_session ) );
    if( info )
      m_certInfo.protocol = info;

    m_valid = true;
  }
Example #14
0
static void mac_bench(int algo, int size)
{
	void *_key;
	int blocksize = gnutls_hmac_get_len(algo);
	int step = size * 1024;
	struct benchmark_st st;
	void *input;
	unsigned char c, *i;

	ALLOCM(input, MAX_MEM);
	i = input;

	_key = malloc(blocksize);
	if (_key == NULL)
		return;
	memset(_key, 0xf0, blocksize);

	printf("%16s ", gnutls_mac_get_name(algo));
	fflush(stdout);

	assert(gnutls_rnd(GNUTLS_RND_NONCE, &c, 1) >= 0);

	start_benchmark(&st);

	do {
		gnutls_hmac_fast(algo, _key, blocksize, i, step, _key);
		st.size += step;
		INC(input, i, step);
	}
	while (benchmark_must_finish == 0);

	stop_benchmark(&st, NULL, 1);
	FREE(input);

	free(_key);
}
Example #15
0
/*
 * This function is called after the TCP connect has completed. Setup the TLS
 * layer and do all necessary magic.
 */
CURLcode
Curl_gtls_connect(struct connectdata *conn,
                  int sockindex)

{
    const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
    struct SessionHandle *data = conn->data;
    gnutls_session session;
    int rc;
    unsigned int cert_list_size;
    const gnutls_datum *chainp;
    unsigned int verify_status;
    gnutls_x509_crt x509_cert;
    char certbuf[256]; /* big enough? */
    size_t size;
    unsigned int algo;
    unsigned int bits;
    time_t clock;
    const char *ptr;
    void *ssl_sessionid;
    size_t ssl_idsize;

    /* GnuTLS only supports TLSv1 (and SSLv3?) */
    if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
        failf(data, "GnuTLS does not support SSLv2");
        return CURLE_SSL_CONNECT_ERROR;
    }

    /* allocate a cred struct */
    rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
    if(rc < 0) {
        failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
        return CURLE_SSL_CONNECT_ERROR;
    }

    if(data->set.ssl.CAfile) {
        /* set the trusted CA cert bundle file */
        gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
                                            GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);

        rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
                data->set.ssl.CAfile,
                GNUTLS_X509_FMT_PEM);
        if(rc < 0) {
            infof(data, "error reading ca cert file %s (%s)\n",
                  data->set.ssl.CAfile, gnutls_strerror(rc));
            if (data->set.ssl.verifypeer)
                return CURLE_SSL_CACERT_BADFILE;
        }
        else
            infof(data, "found %d certificates in %s\n",
                  rc, data->set.ssl.CAfile);
    }

    /* Initialize TLS session as a client */
    rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
    if(rc) {
        failf(data, "gnutls_init() failed: %d", rc);
        return CURLE_SSL_CONNECT_ERROR;
    }

    /* convenient assign */
    session = conn->ssl[sockindex].session;

    /* Use default priorities */
    rc = gnutls_set_default_priority(session);
    if(rc < 0)
        return CURLE_SSL_CONNECT_ERROR;

    /* Sets the priority on the certificate types supported by gnutls. Priority
       is higher for types specified before others. After specifying the types
       you want, you must append a 0. */
    rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
    if(rc < 0)
        return CURLE_SSL_CONNECT_ERROR;

    if(data->set.cert) {
        if( gnutls_certificate_set_x509_key_file(
                    conn->ssl[sockindex].cred, data->set.cert,
                    data->set.key != 0 ? data->set.key : data->set.cert,
                    do_file_type(data->set.cert_type) ) ) {
            failf(data, "error reading X.509 key or certificate file");
            return CURLE_SSL_CONNECT_ERROR;
        }
    }

    /* put the credentials to the current session */
    rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
                                conn->ssl[sockindex].cred);

    /* set the connection handle (file descriptor for the socket) */
    gnutls_transport_set_ptr(session,
                             (gnutls_transport_ptr)conn->sock[sockindex]);

    /* register callback functions to send and receive data. */
    gnutls_transport_set_push_function(session, Curl_gtls_push);
    gnutls_transport_set_pull_function(session, Curl_gtls_pull);

    /* lowat must be set to zero when using custom push and pull functions. */
    gnutls_transport_set_lowat(session, 0);

    /* This might be a reconnect, so we check for a session ID in the cache
       to speed up things */

    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
        /* we got a session id, use it! */
        gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);

        /* Informational message */
        infof (data, "SSL re-using session ID\n");
    }

    rc = handshake(conn, session, sockindex, TRUE);
    if(rc)
        /* handshake() sets its own error message with failf() */
        return rc;

    /* This function will return the peer's raw certificate (chain) as sent by
       the peer. These certificates are in raw format (DER encoded for
       X.509). In case of a X.509 then a certificate list may be present. The
       first certificate in the list is the peer's certificate, following the
       issuer's certificate, then the issuer's issuer etc. */

    chainp = gnutls_certificate_get_peers(session, &cert_list_size);
    if(!chainp) {
        if(data->set.ssl.verifyhost) {
            failf(data, "failed to get server cert");
            return CURLE_SSL_PEER_CERTIFICATE;
        }
        infof(data, "\t common name: WARNING couldn't obtain\n");
    }

    /* This function will try to verify the peer's certificate and return its
       status (trusted, invalid etc.). The value of status should be one or more
       of the gnutls_certificate_status_t enumerated elements bitwise or'd. To
       avoid denial of service attacks some default upper limits regarding the
       certificate key size and chain size are set. To override them use
       gnutls_certificate_set_verify_limits(). */

    rc = gnutls_certificate_verify_peers2(session, &verify_status);
    if (rc < 0) {
        failf(data, "server cert verify failed: %d", rc);
        return CURLE_SSL_CONNECT_ERROR;
    }

    /* verify_status is a bitmask of gnutls_certificate_status bits */
    if(verify_status & GNUTLS_CERT_INVALID) {
        if (data->set.ssl.verifypeer) {
            failf(data, "server certificate verification failed. CAfile: %s",
                  data->set.ssl.CAfile?data->set.ssl.CAfile:"none");
            return CURLE_SSL_CACERT;
        }
        else
            infof(data, "\t server certificate verification FAILED\n");
    }
    else
        infof(data, "\t server certificate verification OK\n");

    /* initialize an X.509 certificate structure. */
    gnutls_x509_crt_init(&x509_cert);

    /* convert the given DER or PEM encoded Certificate to the native
       gnutls_x509_crt_t format */
    gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);

    size=sizeof(certbuf);
    rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
                                       0, /* the first and only one */
                                       FALSE,
                                       certbuf,
                                       &size);
    if(rc) {
        infof(data, "error fetching CN from cert:%s\n",
              gnutls_strerror(rc));
    }

    /* This function will check if the given certificate's subject matches the
       given hostname. This is a basic implementation of the matching described
       in RFC2818 (HTTPS), which takes into account wildcards, and the subject
       alternative name PKIX extension. Returns non zero on success, and zero on
       failure. */
    rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);

    if(!rc) {
        if (data->set.ssl.verifyhost > 1) {
            failf(data, "SSL: certificate subject name (%s) does not match "
                  "target host name '%s'", certbuf, conn->host.dispname);
            gnutls_x509_crt_deinit(x509_cert);
            return CURLE_SSL_PEER_CERTIFICATE;
        }
        else
            infof(data, "\t common name: %s (does not match '%s')\n",
                  certbuf, conn->host.dispname);
    }
    else
        infof(data, "\t common name: %s (matched)\n", certbuf);

    /* Show:

    - ciphers used
    - subject
    - start date
    - expire date
    - common name
    - issuer

    */

    /* public key algorithm's parameters */
    algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
    infof(data, "\t certificate public key: %s\n",
          gnutls_pk_algorithm_get_name(algo));

    /* version of the X.509 certificate. */
    infof(data, "\t certificate version: #%d\n",
          gnutls_x509_crt_get_version(x509_cert));


    size = sizeof(certbuf);
    gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
    infof(data, "\t subject: %s\n", certbuf);

    clock = gnutls_x509_crt_get_activation_time(x509_cert);
    showtime(data, "start date", clock);

    clock = gnutls_x509_crt_get_expiration_time(x509_cert);
    showtime(data, "expire date", clock);

    size = sizeof(certbuf);
    gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
    infof(data, "\t issuer: %s\n", certbuf);

    gnutls_x509_crt_deinit(x509_cert);

    /* compression algorithm (if any) */
    ptr = gnutls_compression_get_name(gnutls_compression_get(session));
    /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
    infof(data, "\t compression: %s\n", ptr);

    /* the name of the cipher used. ie 3DES. */
    ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
    infof(data, "\t cipher: %s\n", ptr);

    /* the MAC algorithms name. ie SHA1 */
    ptr = gnutls_mac_get_name(gnutls_mac_get(session));
    infof(data, "\t MAC: %s\n", ptr);

    if(!ssl_sessionid) {
        /* this session was not previously in the cache, add it now */

        /* get the session ID data size */
        gnutls_session_get_data(session, NULL, &ssl_idsize);
        ssl_sessionid = malloc(ssl_idsize); /* get a buffer for it */

        if(ssl_sessionid) {
            /* extract session ID to the allocated buffer */
            gnutls_session_get_data(session, ssl_sessionid, &ssl_idsize);

            /* store this session id */
            return Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_idsize);
        }
    }

    return CURLE_OK;
}
Example #16
0
int CTlsSocket::Handshake(const CTlsSocket* pPrimarySocket /*=0*/)
{
	m_pOwner->LogMessage(Debug_Verbose, _T("CTlsSocket::Handshake()"));
	wxASSERT(m_session);

	m_tlsState = handshake;

	if (pPrimarySocket)
	{
		// Implicitly trust certificate of primary socket
		unsigned int cert_list_size;
		const gnutls_datum_t* const cert_list = gnutls_certificate_get_peers(pPrimarySocket->m_session, &cert_list_size);
		if (cert_list && cert_list_size)
		{
			m_implicitTrustedCert.data = new unsigned char[cert_list[0].size];
			memcpy(m_implicitTrustedCert.data, cert_list[0].data, cert_list[0].size);
			m_implicitTrustedCert.size = cert_list[0].size;
		}
	}

	int res = gnutls_handshake(m_session);
	if (!res)
	{
		m_pOwner->LogMessage(Debug_Info, _T("Handshake successful"));

		wxString cipherName;
		const char* cipher = gnutls_cipher_get_name(gnutls_cipher_get(m_session));
		if (cipher)
			cipherName = wxString(cipher, wxConvUTF8);
		else
			cipherName = _T("unknown");

		wxString macName;
		const char* mac = gnutls_mac_get_name(gnutls_mac_get(m_session));
		if (mac)
			macName = wxString(mac, wxConvUTF8);
		else
			macName = _T("unknown");

		m_pOwner->LogMessage(Debug_Info, _T("Cipher: %s, MAC: %s"), cipherName.c_str(), macName.c_str());

		res = VerifyCertificate();
		if (res != FZ_REPLY_OK)
			return res;

		m_tlsState = conn;

		wxSocketEvent evt(GetId());
		evt.m_event = wxSOCKET_CONNECTION;
		wxPostEvent(m_pEvtHandler, evt);
		TriggerEvents();

		if (m_shutdown_requested)
		{
			Shutdown();
			if (!Error() || LastError() != wxSOCKET_WOULDBLOCK)
			{
				wxSocketEvent evt(GetId());
				evt.m_event = wxSOCKET_LOST;
				wxPostEvent(m_pEvtHandler, evt);
			}
		}

		return FZ_REPLY_OK;
	}
	else if (res == GNUTLS_E_AGAIN || res == GNUTLS_E_INTERRUPTED)
		return FZ_REPLY_WOULDBLOCK;

	Failure(res);

	return FZ_REPLY_ERROR;
}
Example #17
0
File: pk.c Project: intgr/gnutls
/* in case of DSA puts into data, r,s
 */
static int
_wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo,
                      gnutls_datum_t * signature,
                      const gnutls_datum_t * vdata,
                      const gnutls_pk_params_st * pk_params)
{
  int ret;
  unsigned int hash;
  unsigned int hash_len;

  switch (algo)
    {
    case GNUTLS_PK_EC: /* we do ECDSA */
      {
        ecc_key priv;
        struct dsa_signature sig;
        int curve_id = pk_params->flags;

        if (is_supported_curve(curve_id) == 0)
          return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);

        _ecc_params_to_privkey(pk_params, &priv);

        dsa_signature_init (&sig);

        hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
        if (hash_len > vdata->size)
          {
            gnutls_assert ();
            _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
            hash_len = vdata->size;
          }

        ret = ecc_sign_hash(vdata->data, hash_len,
                            &sig, NULL, rnd_func, &priv, curve_id);
        if (ret != 0)
          {
            gnutls_assert ();
            ret = GNUTLS_E_PK_SIGN_FAILED;
            goto ecdsa_fail;
          }

        ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);

      ecdsa_fail:
        dsa_signature_clear (&sig);
        _ecc_params_clear( &priv);

        if (ret < 0)
          {
            gnutls_assert ();
            goto cleanup;
          }
        break;
      }
    case GNUTLS_PK_DSA:
      {
        struct dsa_public_key pub;
        struct dsa_private_key priv;
        struct dsa_signature sig;

        memset(&priv, 0, sizeof(priv));
        memset(&pub, 0, sizeof(pub));
        _dsa_params_to_pubkey (pk_params, &pub);
        _dsa_params_to_privkey (pk_params, &priv);

        dsa_signature_init (&sig);

        hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
        if (hash_len > vdata->size)
          {
            gnutls_assert ();
            _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
            hash_len = vdata->size;
          }

        ret =
          _dsa_sign (&pub, &priv, NULL, rnd_func,
                     hash_len, vdata->data, &sig);
        if (ret == 0)
          {
            gnutls_assert ();
            ret = GNUTLS_E_PK_SIGN_FAILED;
            goto dsa_fail;
          }

        ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);

      dsa_fail:
        dsa_signature_clear (&sig);

        if (ret < 0)
          {
            gnutls_assert ();
            goto cleanup;
          }
        break;
      }
    case GNUTLS_PK_RSA:
      {
        struct rsa_private_key priv;
        struct rsa_public_key pub;
        mpz_t s;

        _rsa_params_to_privkey (pk_params, &priv);
        _rsa_params_to_pubkey (pk_params, &pub);
        
        mpz_init(s);

        ret = rsa_pkcs1_sign_tr(&pub, &priv, NULL, rnd_func,
                                vdata->size, vdata->data, s);
        if (ret == 0)
          {
            gnutls_assert();
            ret = GNUTLS_E_PK_SIGN_FAILED;
            goto rsa_fail;
          }

        ret = _gnutls_mpi_dprint (s, signature);

rsa_fail:
        mpz_clear(s);

        if (ret < 0)
          {
            gnutls_assert ();
            goto cleanup;
          }

        break;
      }
    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  ret = 0;

cleanup:

  return ret;
}
Example #18
0
         void gtlsGeneric::logSessionInfo(LogWrapperType _logwrapper,
                                          gnutls_session_t _session)
         {
            const char *tmp;
            gnutls_credentials_type_t cred;
            gnutls_kx_algorithm_t kx;

            // print the key exchange's algorithm name
            kx = gnutls_kx_get(_session);
            tmp = gnutls_kx_get_name(kx);
            BTG_NOTICE(_logwrapper, "- Key Exchange: " << tmp);

            // Check the authentication type used and switch
            // to the appropriate.
            cred = gnutls_auth_get_type(_session);
            switch (cred)
               {
               case GNUTLS_CRD_SRP:
                  {
                     BTG_NOTICE(_logwrapper, "- SRP session");
                     break;
                  }

               case GNUTLS_CRD_ANON:
                  {
                     BTG_NOTICE(_logwrapper, "- Anonymous DH using prime of " << gnutls_dh_get_prime_bits (_session) << " bits");
                     break;
                  }
               case GNUTLS_CRD_CERTIFICATE:
                  {
                     // Check if we have been using ephemeral Diffie Hellman.

                     if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
                        {
                           BTG_NOTICE(_logwrapper, "- Ephemeral DH using prime of " << gnutls_dh_get_prime_bits(_session) << " bits");
                        }

                     /* if the certificate list is available, then
                      * print some information about it.
                      */
                     gtlsGeneric::logX509CertificateInfo(_logwrapper, _session);
                     break;
                  }
               default:
                  {
                     BTG_NOTICE(_logwrapper, "Unknown cred.");
                  }
               }

            /* print the protocol's name (ie TLS 1.0)
             */
            tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(_session));
            BTG_NOTICE(_logwrapper, "- Protocol: " << tmp);

            /* print the certificate type of the peer.
             * ie X.509
             */
            tmp = gnutls_certificate_type_get_name(gnutls_certificate_type_get(_session));

            BTG_NOTICE(_logwrapper, "- Certificate Type: " << tmp);

            /* print the compression algorithm (if any)
             */
            tmp = gnutls_compression_get_name(gnutls_compression_get(_session));
            BTG_NOTICE(_logwrapper, "- Compression: " << tmp);

            /* print the name of the cipher used.
             * ie 3DES.
             */
            tmp = gnutls_cipher_get_name(gnutls_cipher_get(_session));
            BTG_NOTICE(_logwrapper, "- Cipher: " << tmp);

            /* Print the MAC algorithms name.
             * ie SHA1
             */
            tmp = gnutls_mac_get_name(gnutls_mac_get(_session));
            BTG_NOTICE(_logwrapper, "- MAC: " << tmp);
         }
Example #19
0
/* tls_negotiate: After TLS state has been initialised, attempt to negotiate
 *   TLS over the wire, including certificate checks. */
static int tls_negotiate (CONNECTION * conn)
{
  tlssockdata *data;
  int err;
  size_t nproto = 0; /* number of tls/ssl protocols */

  data = (tlssockdata *) safe_calloc (1, sizeof (tlssockdata));
  conn->sockdata = data;
  err = gnutls_certificate_allocate_credentials (&data->xcred);
  if (err < 0)
  {
    FREE(&conn->sockdata);
    mutt_error ("gnutls_certificate_allocate_credentials: %s", gnutls_strerror(err));
    mutt_sleep (2);
    return -1;
  }

  gnutls_certificate_set_x509_trust_file (data->xcred, SslCertFile,
					  GNUTLS_X509_FMT_PEM);
  /* ignore errors, maybe file doesn't exist yet */

  if (SslCACertFile)
  {
    gnutls_certificate_set_x509_trust_file (data->xcred, SslCACertFile,
                                            GNUTLS_X509_FMT_PEM);
  }

  if (SslClientCert)
  {
    dprint (2, (debugfile, "Using client certificate %s\n", SslClientCert));
    gnutls_certificate_set_x509_key_file (data->xcred, SslClientCert,
                                          SslClientCert, GNUTLS_X509_FMT_PEM);
  }

#if HAVE_DECL_GNUTLS_VERIFY_DISABLE_TIME_CHECKS
  /* disable checking certificate activation/expiration times
     in gnutls, we do the checks ourselves */
  gnutls_certificate_set_verify_flags(data->xcred, GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
#endif

  if ((err = gnutls_init(&data->state, GNUTLS_CLIENT)))
  {
    mutt_error ("gnutls_handshake: %s", gnutls_strerror(err));
    mutt_sleep (2);
    goto fail;
  }

  /* set socket */
  gnutls_transport_set_ptr (data->state, (gnutls_transport_ptr)conn->fd);

  if (option(OPTTLSV1_2))
    protocol_priority[nproto++] = GNUTLS_TLS1_2;
  if (option(OPTTLSV1_1))
    protocol_priority[nproto++] = GNUTLS_TLS1_1;
  if (option(OPTTLSV1))
    protocol_priority[nproto++] = GNUTLS_TLS1;
  if (option(OPTSSLV3))
    protocol_priority[nproto++] = GNUTLS_SSL3;
  protocol_priority[nproto] = 0;

  /* disable TLS/SSL protocols as needed */
  if (nproto == 0)
  {
    mutt_error (_("All available protocols for TLS/SSL connection disabled"));
    goto fail;
  }
  /*
  else
    use the list set above
  */

  /* We use default priorities (see gnutls documentation),
     except for protocol version */
  gnutls_set_default_priority (data->state);
  gnutls_protocol_set_priority (data->state, protocol_priority);

  if (SslDHPrimeBits > 0)
  {
    gnutls_dh_set_prime_bits (data->state, SslDHPrimeBits);
  }

/*
  gnutls_set_cred (data->state, GNUTLS_ANON, NULL);
*/

  gnutls_credentials_set (data->state, GNUTLS_CRD_CERTIFICATE, data->xcred);

  err = gnutls_handshake(data->state);

  while (err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED)
  {
    err = gnutls_handshake(data->state);
  }
  if (err < 0) {
    if (err == GNUTLS_E_FATAL_ALERT_RECEIVED)
    {
      mutt_error("gnutls_handshake: %s(%s)", gnutls_strerror(err),
		 gnutls_alert_get_name(gnutls_alert_get(data->state)));
    }
    else
    {
      mutt_error("gnutls_handshake: %s", gnutls_strerror(err));
    }
    mutt_sleep (2);
    goto fail;
  }

  if (!tls_check_certificate(conn))
    goto fail;

  /* set Security Strength Factor (SSF) for SASL */
  /* NB: gnutls_cipher_get_key_size() returns key length in bytes */
  conn->ssf = gnutls_cipher_get_key_size (gnutls_cipher_get (data->state)) * 8;

  tls_get_client_cert (conn);

  if (!option(OPTNOCURSES)) {
    mutt_message (_("SSL/TLS connection using %s (%s/%s/%s)"),
                  gnutls_protocol_get_name (gnutls_protocol_get_version (data->state)),
                  gnutls_kx_get_name (gnutls_kx_get (data->state)),
                  gnutls_cipher_get_name (gnutls_cipher_get (data->state)),
                  gnutls_mac_get_name (gnutls_mac_get (data->state)));
    mutt_sleep (0);
  }

  return 0;

 fail:
  gnutls_certificate_free_credentials (data->xcred);
  gnutls_deinit (data->state);
  FREE(&conn->sockdata);
  return -1;
}
Example #20
0
static void cipher_mac_bench(int algo, int mac_algo, int size)
{
	int ret;
	gnutls_cipher_hd_t ctx;
	gnutls_hmac_hd_t mac_ctx;
	void *_key, *_iv;
	gnutls_datum_t key, iv;
	int ivsize = gnutls_cipher_get_iv_size(algo);
	int keysize = gnutls_cipher_get_key_size(algo);
	int step = size * 1024;
	struct benchmark_st st;
	void *output, *input;
	unsigned char c, *i;

	_key = malloc(keysize);
	if (_key == NULL)
		return;
	memset(_key, 0xf0, keysize);

	_iv = malloc(ivsize);
	if (_iv == NULL) {
		free(_key);
		return;
	}
	memset(_iv, 0xf0, ivsize);

	iv.data = _iv;
	iv.size = ivsize;

	key.data = _key;
	key.size = keysize;

	assert(gnutls_rnd(GNUTLS_RND_NONCE, &c, 1) >= 0);

	printf("%19s-%s ", gnutls_cipher_get_name(algo),
	       gnutls_mac_get_name(mac_algo));
	fflush(stdout);

	ALLOCM(input, MAX_MEM);
	ALLOC(output);
	i = input;

	start_benchmark(&st);

	ret = gnutls_hmac_init(&mac_ctx, mac_algo, key.data, key.size);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		goto leave;
	}

	ret = gnutls_cipher_init(&ctx, algo, &key, &iv);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		goto leave;
	}

	do {
		gnutls_hmac(mac_ctx, i, step);
		gnutls_cipher_encrypt2(ctx, i, step, output, step + 64);
		st.size += step;
		INC(input, i, step);
	}
	while (benchmark_must_finish == 0);

	gnutls_cipher_deinit(ctx);
	gnutls_hmac_deinit(mac_ctx, NULL);

	stop_benchmark(&st, NULL, 1);

      leave:
	FREE(input);
	FREE(output);
	free(_key);
	free(_iv);
}
Example #21
0
static void main_texinfo (void)
{
  {
    size_t i;
    const char *name;
    char id[2];
    gnutls_kx_algorithm_t kx;
    gnutls_cipher_algorithm_t cipher;
    gnutls_mac_algorithm_t mac;
    gnutls_protocol_t version;

    printf ("@heading Ciphersuites\n");
    printf ("@multitable @columnfractions .60 .20 .20\n");
    printf("@headitem Ciphersuite name @tab TLS ID @tab Since\n");
    for (i = 0; (name = gnutls_cipher_suite_info
                 (i, id, &kx, &cipher, &mac, &version)); i++)
      {
        printf ("@item %s\n@tab 0x%02X 0x%02X\n@tab %s\n",
                escape_texi_string(name, buffer, sizeof(buffer)),
                (unsigned char) id[0], (unsigned char) id[1],
                gnutls_protocol_get_name (version));
      }
    printf ("@end multitable\n");

  }

  {
    const gnutls_certificate_type_t *p = gnutls_certificate_type_list ();

    printf ("\n\n@heading Certificate types\n");
    printf ("@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_certificate_type_get_name (*p));
      }
    printf ("@end table\n");
  }

  {
    const gnutls_protocol_t *p = gnutls_protocol_list ();

    printf ("\n@heading Protocols\n@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_protocol_get_name (*p));
      }
    printf ("@end table\n");
  }

  {
    const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();

    printf ("\n@heading Ciphers\n@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_cipher_get_name (*p));
      }
    printf ("@end table\n");
  }

  {
    const gnutls_mac_algorithm_t *p = gnutls_mac_list ();

    printf ("\n@heading MAC algorithms\n@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_mac_get_name (*p));
      }
    printf ("@end table\n");
  }

  {
    const gnutls_kx_algorithm_t *p = gnutls_kx_list ();

    printf ("\n@heading Key exchange methods\n@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_kx_get_name (*p));
      }
    printf ("@end table\n");
  }

  {
    const gnutls_pk_algorithm_t *p = gnutls_pk_list ();

    printf ("\n@heading Public key algorithms\n@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_pk_get_name (*p));
      }
    printf ("@end table\n");
  }

  {
    const gnutls_sign_algorithm_t *p = gnutls_sign_list ();

    printf ("\n@heading Public key signature algorithms\n@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_sign_get_name (*p));
      }
    printf ("@end table\n");
  }

  {
    const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list ();

    printf ("\n@heading Elliptic curves\n@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_ecc_curve_get_name (*p));
      }
    printf ("@end table\n");
  }


  {
    const gnutls_compression_method_t *p = gnutls_compression_list ();

    printf ("\n@heading Compression methods\n@table @code\n");
    for (; *p; p++)
      {
        printf ("@item %s\n", gnutls_compression_get_name (*p));
      }
    printf ("@end table\n");
  }
}
Example #22
0
static void cipher_mac_bench(int algo, int mac_algo, int size)
{
	int ret;
	gnutls_cipher_hd_t ctx;
	gnutls_hmac_hd_t mac_ctx;
	void *_key, *_iv;
	gnutls_datum_t key, iv;
	int ivsize = gnutls_cipher_get_iv_size(algo);
	int keysize = gnutls_cipher_get_key_size(algo);
	int step = size * 1024;
	struct benchmark_st st;

	_key = malloc(keysize);
	if (_key == NULL)
		return;
	memset(_key, 0xf0, keysize);

	_iv = malloc(ivsize);
	if (_iv == NULL)
		return;
	memset(_iv, 0xf0, ivsize);

	iv.data = _iv;
	iv.size = ivsize;

	key.data = _key;
	key.size = keysize;

	printf("%16s-%s ", gnutls_cipher_get_name(algo),
	       gnutls_mac_get_name(mac_algo));
	fflush(stdout);

	start_benchmark(&st);

	ret = gnutls_hmac_init(&mac_ctx, mac_algo, key.data, key.size);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		goto leave;
	}

	ret = gnutls_cipher_init(&ctx, algo, &key, &iv);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		goto leave;
	}

	gnutls_hmac(mac_ctx, data, 1024);

	do {
		gnutls_hmac(mac_ctx, data, step);
		gnutls_cipher_encrypt2(ctx, data, step, data, step + 64);
		st.size += step;
	}
	while (benchmark_must_finish == 0);

	gnutls_cipher_deinit(ctx);
	gnutls_hmac_deinit(mac_ctx, NULL);

	stop_benchmark(&st, NULL, 1);

      leave:
	free(_key);
	free(_iv);
}
Example #23
0
static CURLcode
gtls_connect_step3(struct connectdata *conn,
                   int sockindex)
{
  unsigned int cert_list_size;
  const gnutls_datum *chainp;
  unsigned int verify_status;
  gnutls_x509_crt x509_cert,x509_issuer;
  gnutls_datum issuerp;
  char certbuf[256]; /* big enough? */
  size_t size;
  unsigned int algo;
  unsigned int bits;
  time_t certclock;
  const char *ptr;
  struct SessionHandle *data = conn->data;
  gnutls_session session = conn->ssl[sockindex].session;
  int rc;
  int incache;
  void *ssl_sessionid;
  CURLcode result = CURLE_OK;

  /* This function will return the peer's raw certificate (chain) as sent by
     the peer. These certificates are in raw format (DER encoded for
     X.509). In case of a X.509 then a certificate list may be present. The
     first certificate in the list is the peer's certificate, following the
     issuer's certificate, then the issuer's issuer etc. */

  chainp = gnutls_certificate_get_peers(session, &cert_list_size);
  if(!chainp) {
    if(data->set.ssl.verifypeer ||
       data->set.ssl.verifyhost ||
       data->set.ssl.issuercert) {
#ifdef USE_TLS_SRP
      if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
         && data->set.ssl.username != NULL
         && !data->set.ssl.verifypeer
         && gnutls_cipher_get(session)) {
        /* no peer cert, but auth is ok if we have SRP user and cipher and no
           peer verify */
      }
      else {
#endif
        failf(data, "failed to get server cert");
        return CURLE_PEER_FAILED_VERIFICATION;
#ifdef USE_TLS_SRP
      }
#endif
    }
    infof(data, "\t common name: WARNING couldn't obtain\n");
  }

  if(data->set.ssl.verifypeer) {
    /* This function will try to verify the peer's certificate and return its
       status (trusted, invalid etc.). The value of status should be one or
       more of the gnutls_certificate_status_t enumerated elements bitwise
       or'd. To avoid denial of service attacks some default upper limits
       regarding the certificate key size and chain size are set. To override
       them use gnutls_certificate_set_verify_limits(). */

    rc = gnutls_certificate_verify_peers2(session, &verify_status);
    if(rc < 0) {
      failf(data, "server cert verify failed: %d", rc);
      return CURLE_SSL_CONNECT_ERROR;
    }

    /* verify_status is a bitmask of gnutls_certificate_status bits */
    if(verify_status & GNUTLS_CERT_INVALID) {
      if(data->set.ssl.verifypeer) {
        failf(data, "server certificate verification failed. CAfile: %s "
              "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
              data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
        return CURLE_SSL_CACERT;
      }
      else
        infof(data, "\t server certificate verification FAILED\n");
    }
    else
      infof(data, "\t server certificate verification OK\n");
  }
  else {
    infof(data, "\t server certificate verification SKIPPED\n");
    goto after_server_cert_verification;
  }

  /* initialize an X.509 certificate structure. */
  gnutls_x509_crt_init(&x509_cert);

  /* convert the given DER or PEM encoded Certificate to the native
     gnutls_x509_crt_t format */
  gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);

  if(data->set.ssl.issuercert) {
    gnutls_x509_crt_init(&x509_issuer);
    issuerp = load_file(data->set.ssl.issuercert);
    gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
    rc = gnutls_x509_crt_check_issuer(x509_cert,x509_issuer);
    unload_file(issuerp);
    if(rc <= 0) {
      failf(data, "server certificate issuer check failed (IssuerCert: %s)",
            data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
      return CURLE_SSL_ISSUER_ERROR;
    }
    infof(data,"\t server certificate issuer check OK (Issuer Cert: %s)\n",
          data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
  }

  size=sizeof(certbuf);
  rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
                                     0, /* the first and only one */
                                     FALSE,
                                     certbuf,
                                     &size);
  if(rc) {
    infof(data, "error fetching CN from cert:%s\n",
          gnutls_strerror(rc));
  }

  /* This function will check if the given certificate's subject matches the
     given hostname. This is a basic implementation of the matching described
     in RFC2818 (HTTPS), which takes into account wildcards, and the subject
     alternative name PKIX extension. Returns non zero on success, and zero on
     failure. */
  rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);

  if(!rc) {
    if(data->set.ssl.verifyhost) {
      failf(data, "SSL: certificate subject name (%s) does not match "
            "target host name '%s'", certbuf, conn->host.dispname);
      gnutls_x509_crt_deinit(x509_cert);
      return CURLE_PEER_FAILED_VERIFICATION;
    }
    else
      infof(data, "\t common name: %s (does not match '%s')\n",
            certbuf, conn->host.dispname);
  }
  else
    infof(data, "\t common name: %s (matched)\n", certbuf);

  /* Check for time-based validity */
  certclock = gnutls_x509_crt_get_expiration_time(x509_cert);

  if(certclock == (time_t)-1) {
    failf(data, "server cert expiration date verify failed");
    return CURLE_SSL_CONNECT_ERROR;
  }

  if(certclock < time(NULL)) {
    if(data->set.ssl.verifypeer) {
      failf(data, "server certificate expiration date has passed.");
      return CURLE_PEER_FAILED_VERIFICATION;
    }
    else
      infof(data, "\t server certificate expiration date FAILED\n");
  }
  else
    infof(data, "\t server certificate expiration date OK\n");

  certclock = gnutls_x509_crt_get_activation_time(x509_cert);

  if(certclock == (time_t)-1) {
    failf(data, "server cert activation date verify failed");
    return CURLE_SSL_CONNECT_ERROR;
  }

  if(certclock > time(NULL)) {
    if(data->set.ssl.verifypeer) {
      failf(data, "server certificate not activated yet.");
      return CURLE_PEER_FAILED_VERIFICATION;
    }
    else
      infof(data, "\t server certificate activation date FAILED\n");
  }
  else
    infof(data, "\t server certificate activation date OK\n");

  /* Show:

  - ciphers used
  - subject
  - start date
  - expire date
  - common name
  - issuer

  */

  /* public key algorithm's parameters */
  algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
  infof(data, "\t certificate public key: %s\n",
        gnutls_pk_algorithm_get_name(algo));

  /* version of the X.509 certificate. */
  infof(data, "\t certificate version: #%d\n",
        gnutls_x509_crt_get_version(x509_cert));


  size = sizeof(certbuf);
  gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
  infof(data, "\t subject: %s\n", certbuf);

  certclock = gnutls_x509_crt_get_activation_time(x509_cert);
  showtime(data, "start date", certclock);

  certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
  showtime(data, "expire date", certclock);

  size = sizeof(certbuf);
  gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
  infof(data, "\t issuer: %s\n", certbuf);

  gnutls_x509_crt_deinit(x509_cert);

after_server_cert_verification:

  /* compression algorithm (if any) */
  ptr = gnutls_compression_get_name(gnutls_compression_get(session));
  /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
  infof(data, "\t compression: %s\n", ptr);

  /* the name of the cipher used. ie 3DES. */
  ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
  infof(data, "\t cipher: %s\n", ptr);

  /* the MAC algorithms name. ie SHA1 */
  ptr = gnutls_mac_get_name(gnutls_mac_get(session));
  infof(data, "\t MAC: %s\n", ptr);

  conn->ssl[sockindex].state = ssl_connection_complete;
  conn->recv[sockindex] = gtls_recv;
  conn->send[sockindex] = gtls_send;

  {
    /* we always unconditionally get the session id here, as even if we
       already got it from the cache and asked to use it in the connection, it
       might've been rejected and then a new one is in use now and we need to
       detect that. */
    void *connect_sessionid;
    size_t connect_idsize;

    /* get the session ID data size */
    gnutls_session_get_data(session, NULL, &connect_idsize);
    connect_sessionid = malloc(connect_idsize); /* get a buffer for it */

    if(connect_sessionid) {
      /* extract session ID to the allocated buffer */
      gnutls_session_get_data(session, connect_sessionid, &connect_idsize);

      incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
      if(incache) {
        /* there was one before in the cache, so instead of risking that the
           previous one was rejected, we just kill that and store the new */
        Curl_ssl_delsessionid(conn, ssl_sessionid);
      }

      /* store this session id */
      result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
      if(result) {
        free(connect_sessionid);
        result = CURLE_OUT_OF_MEMORY;
      }
    }
    else
      result = CURLE_OUT_OF_MEMORY;
  }

  return result;
}
Example #24
0
/**
 * gnutls_session_get_desc:
 * @session: is a gnutls session
 *
 * This function returns a string describing the current session.
 * The string is null terminated and allocated using gnutls_malloc().
 *
 * Returns: a description of the protocols and algorithms in the current session.
 *
 * Since: 3.1.10
 **/
char *gnutls_session_get_desc(gnutls_session_t session)
{
	gnutls_kx_algorithm_t kx;
	unsigned type;
	char kx_name[32];
	char proto_name[32];
	const char *curve_name = NULL;
	unsigned dh_bits = 0;
	unsigned mac_id;
	char *desc;

	kx = session->security_parameters.kx_algorithm;

	if (kx == GNUTLS_KX_ANON_ECDH || kx == GNUTLS_KX_ECDHE_PSK ||
	    kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA) {
		curve_name =
		    gnutls_ecc_curve_get_name(gnutls_ecc_curve_get
					      (session));
	} else if (kx == GNUTLS_KX_ANON_DH || kx == GNUTLS_KX_DHE_PSK
		   || kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) {
		dh_bits = gnutls_dh_get_prime_bits(session);
	}

	if (curve_name != NULL)
		snprintf(kx_name, sizeof(kx_name), "%s-%s",
			 gnutls_kx_get_name(kx), curve_name);
	else if (dh_bits != 0)
		snprintf(kx_name, sizeof(kx_name), "%s-%u",
			 gnutls_kx_get_name(kx), dh_bits);
	else
		snprintf(kx_name, sizeof(kx_name), "%s",
			 gnutls_kx_get_name(kx));

	type = gnutls_certificate_type_get(session);
	if (type == GNUTLS_CRT_X509)
		snprintf(proto_name, sizeof(proto_name), "%s",
			 gnutls_protocol_get_name(get_num_version
						  (session)));
	else
		snprintf(proto_name, sizeof(proto_name), "%s-%s",
			 gnutls_protocol_get_name(get_num_version
						  (session)),
			 gnutls_certificate_type_get_name(type));

	gnutls_protocol_get_name(get_num_version(session)),
	    desc = gnutls_malloc(DESC_SIZE);
	if (desc == NULL)
		return NULL;

	mac_id = gnutls_mac_get(session);
	if (mac_id == GNUTLS_MAC_AEAD) { /* no need to print */
		snprintf(desc, DESC_SIZE,
			 "(%s)-(%s)-(%s)",
			 proto_name,
			 kx_name,
			 gnutls_cipher_get_name(gnutls_cipher_get(session)));
	} else {
		snprintf(desc, DESC_SIZE,
			 "(%s)-(%s)-(%s)-(%s)",
			 proto_name,
			 kx_name,
			 gnutls_cipher_get_name(gnutls_cipher_get(session)),
			 gnutls_mac_get_name(mac_id));
	}

	return desc;
}
Example #25
0
/* Hashes input data and verifies a DSA signature.
 */
static int
dsa_verify_sig (const gnutls_datum_t * text,
                const gnutls_datum_t * hash,
                const gnutls_datum_t * signature, bigint_t * params,
                int params_len)
{
  int ret;
  opaque _digest[MAX_HASH_SIZE];
  gnutls_datum_t digest;
  digest_hd_st hd;
  gnutls_digest_algorithm_t algo;
  unsigned int hash_len;

  algo = _gnutls_dsa_q_to_hash (params[1], &hash_len);
  if (hash)
    {
      /* SHA1 or better allowed */
      if (!hash->data || hash->size < hash_len)
        {
          gnutls_assert();
          _gnutls_debug_log("Hash size (%d) does not correspond to hash %s", (int)hash->size, gnutls_mac_get_name(algo));
          
          if (hash->size != 20)
            return GNUTLS_E_PK_SIG_VERIFY_FAILED;
        }
      digest = *hash;
    }
  else
    {

      ret = _gnutls_hash_init (&hd, algo);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

      _gnutls_hash (&hd, text->data, text->size);
      _gnutls_hash_deinit (&hd, _digest);

      digest.data = _digest;
      digest.size = _gnutls_hash_get_algo_len(algo);
    }

  ret = _gnutls_dsa_verify (&digest, signature, params, params_len);

  return ret;
}
Example #26
0
/* This function will print some details of the
 * given session.
 */
int
print_info (gnutls_session_t session)
{
  const char *tmp;
  gnutls_credentials_type_t cred;
  gnutls_kx_algorithm_t kx;

  /* print the key exchange's algorithm name
   */
  kx = gnutls_kx_get (session);
  tmp = gnutls_kx_get_name (kx);
  printf ("- Key Exchange: %s\n", tmp);

  /* Check the authentication type used and switch
   * to the appropriate.
   */
  cred = gnutls_auth_get_type (session);
  switch (cred)
    {
    case GNUTLS_CRD_IA:
      printf ("- TLS/IA session\n");
      break;


#ifdef ENABLE_SRP
    case GNUTLS_CRD_SRP:
      printf ("- SRP session with username %s\n",
	      gnutls_srp_server_get_username (session));
      break;
#endif

    case GNUTLS_CRD_PSK:
      /* This returns NULL in server side.
       */
      if (gnutls_psk_client_get_hint (session) != NULL)
	printf ("- PSK authentication. PSK hint '%s'\n",
		gnutls_psk_client_get_hint (session));
      /* This returns NULL in client side.
       */
      if (gnutls_psk_server_get_username (session) != NULL)
	printf ("- PSK authentication. Connected as '%s'\n",
		gnutls_psk_server_get_username (session));
      break;

    case GNUTLS_CRD_ANON:	/* anonymous authentication */

      printf ("- Anonymous DH using prime of %d bits\n",
	      gnutls_dh_get_prime_bits (session));
      break;

    case GNUTLS_CRD_CERTIFICATE:	/* certificate authentication */

      /* Check if we have been using ephemeral Diffie-Hellman.
       */
      if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
	{
	  printf ("\n- Ephemeral DH using prime of %d bits\n",
		  gnutls_dh_get_prime_bits (session));
	}

      /* if the certificate list is available, then
       * print some information about it.
       */
      print_x509_certificate_info (session);

    }				/* switch */

  /* print the protocol's name (ie TLS 1.0) 
   */
  tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session));
  printf ("- Protocol: %s\n", tmp);

  /* print the certificate type of the peer.
   * ie X.509
   */
  tmp =
    gnutls_certificate_type_get_name (gnutls_certificate_type_get (session));

  printf ("- Certificate Type: %s\n", tmp);

  /* print the compression algorithm (if any)
   */
  tmp = gnutls_compression_get_name (gnutls_compression_get (session));
  printf ("- Compression: %s\n", tmp);

  /* print the name of the cipher used.
   * ie 3DES.
   */
  tmp = gnutls_cipher_get_name (gnutls_cipher_get (session));
  printf ("- Cipher: %s\n", tmp);

  /* Print the MAC algorithms name.
   * ie SHA1
   */
  tmp = gnutls_mac_get_name (gnutls_mac_get (session));
  printf ("- MAC: %s\n", tmp);

  return 0;
}
Example #27
0
File: common.c Project: sqs/gnutls
void
print_list (int verbose)
{
  {
    size_t i;
    const char *name;
    char id[2];
    gnutls_kx_algorithm_t kx;
    gnutls_cipher_algorithm_t cipher;
    gnutls_mac_algorithm_t mac;
    gnutls_protocol_t version;

    printf ("Cipher suites:\n");
    for (i = 0; (name = gnutls_cipher_suite_info
                 (i, id, &kx, &cipher, &mac, &version)); i++)
      {
        printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
                name,
                (unsigned char) id[0], (unsigned char) id[1],
                gnutls_protocol_get_name (version));
        if (verbose)
          printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
                  gnutls_kx_get_name (kx),
                  gnutls_cipher_get_name (cipher), gnutls_mac_get_name (mac));
      }
  }

  {
    const gnutls_certificate_type_t *p = gnutls_certificate_type_list ();

    printf ("Certificate types: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_certificate_type_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_protocol_t *p = gnutls_protocol_list ();

    printf ("Protocols: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_protocol_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();

    printf ("Ciphers: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_cipher_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_mac_algorithm_t *p = gnutls_mac_list ();

    printf ("MACs: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_mac_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_kx_algorithm_t *p = gnutls_kx_list ();

    printf ("Key exchange algorithms: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_kx_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_compression_method_t *p = gnutls_compression_list ();

    printf ("Compression: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_compression_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_pk_algorithm_t *p = gnutls_pk_list ();

    printf ("Public Key Systems: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_pk_algorithm_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_sign_algorithm_t *p = gnutls_sign_list ();

    printf ("PK-signatures: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_sign_algorithm_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }
}
Example #28
0
int
print_info (gnutls_session_t session, int print_cert)
{
    const char *tmp;
    gnutls_credentials_type_t cred;
    gnutls_kx_algorithm_t kx;
    unsigned char session_id[33];
    size_t session_id_size = sizeof (session_id);

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

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

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

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

          print_cert_info (session, 
                           verbose?GNUTLS_CRT_PRINT_FULL:GNUTLS_CRT_PRINT_COMPACT, 
                           print_cert);

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

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

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

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

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

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

    if (verbose)
      {
          gnutls_datum_t cb;
          int rc;

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

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

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

    fflush (stdout);

    return 0;
}
Example #29
0
void
print_list (const char *priorities, int verbose)
{
    size_t i;
    int ret;
    unsigned int idx;
    const char *name;
    const char *err;
    unsigned char id[2];
    gnutls_kx_algorithm_t kx;
    gnutls_cipher_algorithm_t cipher;
    gnutls_mac_algorithm_t mac;
    gnutls_protocol_t version;
    gnutls_priority_t pcache;
    const unsigned int *list;

    if (priorities != NULL)
      {
          printf ("Cipher suites for %s\n", priorities);

          ret = gnutls_priority_init (&pcache, priorities, &err);
          if (ret < 0)
            {
                fprintf (stderr, "Syntax error at: %s\n", err);
                exit (1);
            }

          for (i = 0;; i++)
            {
                ret =
                    gnutls_priority_get_cipher_suite_index (pcache, i,
                                                            &idx);
                if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
                    break;
                if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE)
                    continue;

                name =
                    gnutls_cipher_suite_info (idx, id, NULL, NULL, NULL,
                                              &version);

                if (name != NULL)
                    printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
                            name, (unsigned char) id[0],
                            (unsigned char) id[1],
                            gnutls_protocol_get_name (version));
            }

          printf("\n");
          {
              ret = gnutls_priority_certificate_type_list (pcache, &list);

              printf ("Certificate types: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("CTYPE-%s",
                            gnutls_certificate_type_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          {
              ret = gnutls_priority_protocol_list (pcache, &list);

              printf ("Protocols: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("VERS-%s", gnutls_protocol_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          {
              ret = gnutls_priority_compression_list (pcache, &list);

              printf ("Compression: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("COMP-%s",
                            gnutls_compression_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          {
              ret = gnutls_priority_ecc_curve_list (pcache, &list);

              printf ("Elliptic curves: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("CURVE-%s",
                            gnutls_ecc_curve_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          {
              ret = gnutls_priority_sign_list (pcache, &list);

              printf ("PK-signatures: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("SIGN-%s",
                            gnutls_sign_algorithm_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          return;
      }

    printf ("Cipher suites:\n");
    for (i = 0; (name = gnutls_cipher_suite_info
                 (i, id, &kx, &cipher, &mac, &version)); i++)
      {
          printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
                  name,
                  (unsigned char) id[0], (unsigned char) id[1],
                  gnutls_protocol_get_name (version));
          if (verbose)
              printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
                      gnutls_kx_get_name (kx),
                      gnutls_cipher_get_name (cipher),
                      gnutls_mac_get_name (mac));
      }

    printf("\n");
    {
        const gnutls_certificate_type_t *p =
            gnutls_certificate_type_list ();

        printf ("Certificate types: ");
        for (; *p; p++)
          {
              printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_protocol_t *p = gnutls_protocol_list ();

        printf ("Protocols: ");
        for (; *p; p++)
          {
              printf ("VERS-%s", gnutls_protocol_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();

        printf ("Ciphers: ");
        for (; *p; p++)
          {
              printf ("%s", gnutls_cipher_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_mac_algorithm_t *p = gnutls_mac_list ();

        printf ("MACs: ");
        for (; *p; p++)
          {
              printf ("%s", gnutls_mac_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_kx_algorithm_t *p = gnutls_kx_list ();

        printf ("Key exchange algorithms: ");
        for (; *p; p++)
          {
              printf ("%s", gnutls_kx_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_compression_method_t *p = gnutls_compression_list ();

        printf ("Compression: ");
        for (; *p; p++)
          {
              printf ("COMP-%s", gnutls_compression_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list ();

        printf ("Elliptic curves: ");
        for (; *p; p++)
          {
              printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_pk_algorithm_t *p = gnutls_pk_list ();

        printf ("Public Key Systems: ");
        for (; *p; p++)
          {
              printf ("%s", gnutls_pk_algorithm_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_sign_algorithm_t *p = gnutls_sign_list ();

        printf ("PK-signatures: ");
        for (; *p; p++)
          {
              printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }
}
Example #30
0
/**
 * gnutls_session_get_desc:
 * @session: is a gnutls session
 *
 * This function returns a string describing the current session.
 * The string is null terminated and allocated using gnutls_malloc().
 *
 * If initial negotiation is not complete when this function is called,
 * %NULL will be returned.
 *
 * Returns: a description of the protocols and algorithms in the current session.
 *
 * Since: 3.1.10
 **/
char *gnutls_session_get_desc(gnutls_session_t session)
{
	gnutls_kx_algorithm_t kx;
	const char *kx_str;
	unsigned type;
	char kx_name[32];
	char proto_name[32];
	const char *curve_name = NULL;
	unsigned dh_bits = 0;
	unsigned mac_id;
	char *desc;

	if (session->internals.initial_negotiation_completed == 0)
		return NULL;

	kx = session->security_parameters.kx_algorithm;

	if (kx == GNUTLS_KX_ANON_ECDH || kx == GNUTLS_KX_ECDHE_PSK ||
	    kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA) {
		curve_name =
		    gnutls_ecc_curve_get_name(gnutls_ecc_curve_get
					      (session));
#if defined(ENABLE_DHE) || defined(ENABLE_ANON)
	} else if (kx == GNUTLS_KX_ANON_DH || kx == GNUTLS_KX_DHE_PSK
		   || kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) {
		dh_bits = gnutls_dh_get_prime_bits(session);
#endif
	}

	kx_str = gnutls_kx_get_name(kx);
	if (kx_str) {
		if (curve_name != NULL)
			snprintf(kx_name, sizeof(kx_name), "%s-%s",
				 kx_str, curve_name);
		else if (dh_bits != 0)
			snprintf(kx_name, sizeof(kx_name), "%s-%u",
				 kx_str, dh_bits);
		else
			snprintf(kx_name, sizeof(kx_name), "%s",
				 kx_str);
	} else {
		strcpy(kx_name, "NULL");
	}

	type = gnutls_certificate_type_get(session);
	if (type == GNUTLS_CRT_X509)
		snprintf(proto_name, sizeof(proto_name), "%s",
			 gnutls_protocol_get_name(get_num_version
						  (session)));
	else
		snprintf(proto_name, sizeof(proto_name), "%s-%s",
			 gnutls_protocol_get_name(get_num_version
						  (session)),
			 gnutls_certificate_type_get_name(type));

	desc = gnutls_malloc(DESC_SIZE);
	if (desc == NULL)
		return NULL;

	mac_id = gnutls_mac_get(session);
	if (mac_id == GNUTLS_MAC_AEAD) { /* no need to print */
		snprintf(desc, DESC_SIZE,
			 "(%s)-(%s)-(%s)",
			 proto_name,
			 kx_name,
			 gnutls_cipher_get_name(gnutls_cipher_get(session)));
	} else {
		snprintf(desc, DESC_SIZE,
			 "(%s)-(%s)-(%s)-(%s)",
			 proto_name,
			 kx_name,
			 gnutls_cipher_get_name(gnutls_cipher_get(session)),
			 gnutls_mac_get_name(mac_id));
	}

	return desc;
}