Exemple #1
0
/**
 * gnutls_certificate_verify_peers2:
 * @session: is a gnutls session
 * @status: is the output of the verification
 *
 * 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().
 *
 * Note that you must also check the peer's name in order to check if
 * the verified certificate belongs to the actual peer, see gnutls_x509_crt_check_hostname().
 *
 * Returns: a negative error code on error and %GNUTLS_E_SUCCESS (0) on success.
 **/
int
gnutls_certificate_verify_peers2 (gnutls_session_t session,
                                  unsigned int *status)
{
  cert_auth_info_t info;

  CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      return GNUTLS_E_NO_CERTIFICATE_FOUND;
    }

  if (info->raw_certificate_list == NULL || info->ncerts == 0)
    return GNUTLS_E_NO_CERTIFICATE_FOUND;

  switch (gnutls_certificate_type_get (session))
    {
    case GNUTLS_CRT_X509:
      return _gnutls_x509_cert_verify_peers (session, status);
#ifdef ENABLE_OPENPGP
    case GNUTLS_CRT_OPENPGP:
      return _gnutls_openpgp_crt_verify_peers (session, status);
#endif
    default:
      return GNUTLS_E_INVALID_REQUEST;
    }
}
Exemple #2
0
/**
 * gnutls_certificate_expiration_time_peers:
 * @session: is a gnutls session
 *
 * This function will return the peer's certificate expiration time.
 *
 * Returns: (time_t)-1 on error.
 *
 * Deprecated: gnutls_certificate_verify_peers2() now verifies expiration times.
 **/
time_t
gnutls_certificate_expiration_time_peers (gnutls_session_t session)
{
  cert_auth_info_t info;

  CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      return (time_t) - 1;
    }

  if (info->raw_certificate_list == NULL || info->ncerts == 0)
    {
      gnutls_assert ();
      return (time_t) - 1;
    }

  switch (gnutls_certificate_type_get (session))
    {
    case GNUTLS_CRT_X509:
      return
        _gnutls_x509_get_raw_crt_expiration_time (&info->raw_certificate_list
                                                  [0]);
#ifdef ENABLE_OPENPGP
    case GNUTLS_CRT_OPENPGP:
      return
        _gnutls_openpgp_get_raw_key_expiration_time
        (&info->raw_certificate_list[0]);
#endif
    default:
      return (time_t) - 1;
    }
}
Exemple #3
0
/* just read the username from the client key exchange.
 */
int
_gnutls_proc_psk_client_kx (gnutls_session_t session, opaque * data,
                            size_t _data_size)
{
  ssize_t data_size = _data_size;
  int ret;
  gnutls_datum_t username;
  gnutls_psk_server_credentials_t cred;
  psk_auth_info_t info;

  cred = (gnutls_psk_server_credentials_t)
    _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL);

  if (cred == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  if ((ret =
       _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
                              sizeof (psk_auth_info_st), 1)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  DECR_LEN (data_size, 2);
  username.size = _gnutls_read_uint16 (&data[0]);

  DECR_LEN (data_size, username.size);

  username.data = &data[2];


  /* copy the username to the auth info structures
   */
  info = _gnutls_get_auth_info (session);

  if (username.size > MAX_USERNAME_SIZE)
    {
      gnutls_assert ();
      return GNUTLS_E_ILLEGAL_SRP_USERNAME;
    }

  memcpy (info->username, username.data, username.size);
  info->username[username.size] = 0;

  ret = _gnutls_set_psk_session_key (session, NULL);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  ret = 0;

error:
  return ret;
}
Exemple #4
0
/* Generates the PSK client key exchange
 *
 * 
 * struct {
 *    select (KeyExchangeAlgorithm) {
 *       uint8_t psk_identity<0..2^16-1>;
 *    } exchange_keys;
 * } ClientKeyExchange;
 *
 */
int
_gnutls_gen_psk_client_kx(gnutls_session_t session,
			  gnutls_buffer_st * data)
{
	int ret, free;
	gnutls_datum_t username = {NULL, 0};
	gnutls_datum_t key;
	gnutls_psk_client_credentials_t cred;
	psk_auth_info_t info;

	cred = (gnutls_psk_client_credentials_t)
	    _gnutls_get_cred(session, GNUTLS_CRD_PSK);

	if (cred == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
	if (info == NULL) {
		gnutls_assert();
		return GNUTLS_E_INTERNAL_ERROR;
	}

	ret = _gnutls_find_psk_key(session, cred, &username, &key, &free);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_set_psk_session_key(session, &key, NULL);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_buffer_append_data_prefix(data, 16, username.data,
					      username.size);
	if (ret < 0) {
		gnutls_assert();
	}

	if (username.size > sizeof(info->username)-1) {
		gnutls_assert();
		ret = GNUTLS_E_ILLEGAL_SRP_USERNAME;
		goto cleanup;
	}

	assert(username.data != NULL);
	memcpy(info->username, username.data, username.size);
	info->username[username.size] = 0;


      cleanup:
	if (free) {
		gnutls_free(username.data);
		_gnutls_free_temp_key_datum(&key);
	}

	return ret;
}
Exemple #5
0
/**
 * gnutls_dh_get_prime_bits:
 * @session: is a gnutls session
 *
 * This function will return the bits of the prime used in the last
 * Diffie-Hellman key exchange with the peer.  Should be used for both
 * anonymous and ephemeral Diffie-Hellman.  Note that some ciphers,
 * like RSA and DSA without DHE, do not use a Diffie-Hellman key
 * exchange, and then this function will return 0.
 *
 * Returns: The Diffie-Hellman bit strength is returned, or 0 if no
 *   Diffie-Hellman key exchange was done, or a negative error code on
 *   failure.
 **/
int gnutls_dh_get_prime_bits(gnutls_session_t session)
{
	dh_info_st *dh;

	switch (gnutls_auth_get_type(session)) {
	case GNUTLS_CRD_ANON:
		{
			anon_auth_info_t info;

			info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
			if (info == NULL)
				return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
			dh = &info->dh;
			break;
		}
	case GNUTLS_CRD_PSK:
		{
			psk_auth_info_t info;

			info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
			if (info == NULL)
				return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
			dh = &info->dh;
			break;
		}
	case GNUTLS_CRD_CERTIFICATE:
		{
			cert_auth_info_t info;

			info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
			if (info == NULL)
				return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

			dh = &info->dh;
			break;
		}
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if(dh->prime.size == 0)
		return 0;

	return mpi_buf2bits(&dh->prime);
}
Exemple #6
0
/*-
  * _gnutls_openpgp_crt_verify_peers - This function returns the peer's certificate status
  * @session: is a gnutls session
  *
  * This function will try to verify the peer's certificate and return its status (TRUSTED, INVALID etc.). 
  * Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
  *
  -*/
int
_gnutls_openpgp_crt_verify_peers (gnutls_session_t session,
				   unsigned int *status)
{
  cert_auth_info_t info;
  gnutls_certificate_credentials_t cred;
  int peer_certificate_list_size, ret;

  CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    return GNUTLS_E_INVALID_REQUEST;

  cred = (gnutls_certificate_credentials_t)
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
  if (cred == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  if (info->raw_certificate_list == NULL || info->ncerts == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_NO_CERTIFICATE_FOUND;
    }

  /* generate a list of gnutls_certs based on the auth info
   * raw certs.
   */
  peer_certificate_list_size = info->ncerts;

  if (peer_certificate_list_size != 1)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* Verify certificate 
   */
  if (_E_gnutls_openpgp_verify_key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INIT_LIBEXTRA;
    }
  ret =
    _E_gnutls_openpgp_verify_key (cred, &info->raw_certificate_list[0],
				  peer_certificate_list_size, status);

  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return 0;
}
Exemple #7
0
static int
unpack_psk_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  size_t username_size, hint_size;
  int ret;
  psk_auth_info_t info;

  ret =
    _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
                           sizeof (psk_auth_info_st), 1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  BUFFER_POP_NUM (ps, username_size);
  if (username_size > sizeof (info->username))
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  BUFFER_POP (ps, info->username, username_size);

  BUFFER_POP_NUM (ps, hint_size);
  if (hint_size > sizeof (info->hint))
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }
  BUFFER_POP (ps, info->hint, hint_size);

  BUFFER_POP_NUM (ps, info->dh.secret_bits);

  BUFFER_POP_DATUM (ps, &info->dh.prime);
  BUFFER_POP_DATUM (ps, &info->dh.generator);
  BUFFER_POP_DATUM (ps, &info->dh.public_key);

  ret = 0;

error:
  _gnutls_free_datum (&info->dh.prime);
  _gnutls_free_datum (&info->dh.generator);
  _gnutls_free_datum (&info->dh.public_key);

  return ret;
}
Exemple #8
0
/**
 * gnutls_dh_get_pubkey:
 * @session: is a gnutls session
 * @raw_key: will hold the public key.
 *
 * This function will return the peer's public key used in the last
 * Diffie-Hellman key exchange.  This function should be used for both
 * anonymous and ephemeral Diffie-Hellman.  The output parameters must
 * be freed with gnutls_free().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
 *   an error code is returned.
 **/
int
gnutls_dh_get_pubkey(gnutls_session_t session, gnutls_datum_t * raw_key)
{
	dh_info_st *dh;
	anon_auth_info_t anon_info;
	cert_auth_info_t cert_info;
	cert_auth_info_t psk_info;

	switch (gnutls_auth_get_type(session)) {
	case GNUTLS_CRD_ANON:
		{
			anon_info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
			if (anon_info == NULL)
				return GNUTLS_E_INTERNAL_ERROR;
			dh = &anon_info->dh;
			break;
		}
	case GNUTLS_CRD_PSK:
		{
			psk_info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
			if (psk_info == NULL)
				return GNUTLS_E_INTERNAL_ERROR;
			dh = &psk_info->dh;
			break;
		}
	case GNUTLS_CRD_CERTIFICATE:
		{

			cert_info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
			if (cert_info == NULL)
				return GNUTLS_E_INTERNAL_ERROR;
			dh = &cert_info->dh;
			break;
		}
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	return _gnutls_set_datum(raw_key, dh->public_key.data,
				 dh->public_key.size);
}
Exemple #9
0
/**
 * gnutls_srp_server_get_username:
 * @session: is a gnutls session
 *
 * This function will return the username of the peer.  This should
 * only be called in case of SRP authentication and in case of a
 * server.  Returns NULL in case of an error.
 *
 * Returns: SRP username of the peer, or NULL in case of error.
 **/
const char *gnutls_srp_server_get_username(gnutls_session_t session)
{
	srp_server_auth_info_t info;

	CHECK_AUTH(GNUTLS_CRD_SRP, NULL);

	info = _gnutls_get_auth_info(session, GNUTLS_CRD_SRP);
	if (info == NULL)
		return NULL;
	return info->username;
}
Exemple #10
0
/* just read the hint from the server key exchange.
 */
static int
_gnutls_proc_psk_server_kx(gnutls_session_t session, uint8_t * data,
			   size_t _data_size)
{
	ssize_t data_size = _data_size;
	int ret;
	gnutls_datum_t hint;
	gnutls_psk_client_credentials_t cred;
	psk_auth_info_t info;

	cred = (gnutls_psk_client_credentials_t)
	    _gnutls_get_cred(session, GNUTLS_CRD_PSK);

	if (cred == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	if ((ret =
	     _gnutls_auth_info_set(session, GNUTLS_CRD_PSK,
				   sizeof(psk_auth_info_st), 1)) < 0) {
		gnutls_assert();
		return ret;
	}

	DECR_LENGTH_RET(data_size, 2, 0);
	hint.size = _gnutls_read_uint16(&data[0]);

	DECR_LEN(data_size, hint.size);

	hint.data = &data[2];

	/* copy the hint to the auth info structures
	 */
	info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
	if (info == NULL) {
		gnutls_assert();
		return GNUTLS_E_INTERNAL_ERROR;
	}

	if (hint.size > sizeof(info->hint)-1) {
		gnutls_assert();
		return GNUTLS_E_ILLEGAL_SRP_USERNAME;
	}

	memcpy(info->hint, hint.data, hint.size);
	info->hint[hint.size] = 0;

	ret = 0;

	return ret;
}
Exemple #11
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 */
static int
pack_anon_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
{
  anon_auth_info_t info = _gnutls_get_auth_info (session);
  int pos = 0;
  size_t pack_size;

  if (info == NULL && session->key->auth_info_size != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (info)
    pack_size = 2 + 4 * 3 + info->dh.prime.size +
      info->dh.generator.size + info->dh.public_key.size;
  else
    pack_size = 0;

  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);

  /* calculate the size and allocate the data.
   */
  packed_session->data =
    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);

  if (packed_session->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  packed_session->data[0] = GNUTLS_CRD_ANON;
  _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
  pos += 4 + PACK_HEADER_SIZE;

  if (pack_size > 0)
    {
      _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
      pos += 2;

      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
      pos += 4 + info->dh.prime.size;
      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
      pos += 4 + info->dh.generator.size;
      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
      pos += 4 + info->dh.public_key.size;

    }

  return 0;
}
Exemple #12
0
/* This function reads the RSA parameters from peer's certificate;
 */
int
_gnutls_get_public_rsa_params(gnutls_session_t session,
			      gnutls_pk_params_st * params)
{
	int ret;
	cert_auth_info_t info;
	unsigned key_usage;
	gnutls_pcert_st peer_cert;

	/* normal non export case */

	info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);

	if (info == NULL || info->ncerts == 0) {
		gnutls_assert();
		return GNUTLS_E_INTERNAL_ERROR;
	}

	ret =
	    _gnutls_get_auth_info_pcert(&peer_cert,
					session->security_parameters.
					cert_type, info);

	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	gnutls_pubkey_get_key_usage(peer_cert.pubkey, &key_usage);

	ret = check_key_usage_for_enc(session, key_usage);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup2;
	}

	gnutls_pk_params_init(params);

	ret = _gnutls_pubkey_get_mpis(peer_cert.pubkey, params);
	if (ret < 0) {
		ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
		goto cleanup2;
	}

	gnutls_pcert_deinit(&peer_cert);
	return 0;

      cleanup2:
	gnutls_pcert_deinit(&peer_cert);

	return ret;
}
Exemple #13
0
static int
unpack_srp_auth_info (gnutls_session_t session,
		      const gnutls_datum_t * packed_session)
{
  size_t username_size;
  int ret;
  srp_server_auth_info_t info;

  if (packed_session->data[0] != GNUTLS_CRD_SRP)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  username_size =
    _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);

  if (username_size == 0)
    return 0;			/* nothing to be done */

  /* a simple check for integrity */
  if (username_size + 4 + PACK_HEADER_SIZE > packed_session->size)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  ret =
    _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
			   sizeof (srp_server_auth_info_st), 1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  memcpy (info->username,
	  &packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
	  username_size);

  return 0;
}
Exemple #14
0
/**
 * gnutls_dh_get_secret_bits:
 * @session: is a gnutls session
 *
 * This function will return the bits used in the last Diffie-Hellman
 * key exchange with the peer.  Should be used for both anonymous and
 * ephemeral Diffie-Hellman.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
 *   an error code is returned.
 **/
int gnutls_dh_get_secret_bits(gnutls_session_t session)
{
	switch (gnutls_auth_get_type(session)) {
	case GNUTLS_CRD_ANON:
		{
			anon_auth_info_t info;

			info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
			if (info == NULL)
				return GNUTLS_E_INTERNAL_ERROR;
			return info->dh.secret_bits;
		}
	case GNUTLS_CRD_PSK:
		{
			psk_auth_info_t info;

			info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
			if (info == NULL)
				return GNUTLS_E_INTERNAL_ERROR;
			return info->dh.secret_bits;
		}
	case GNUTLS_CRD_CERTIFICATE:
		{
			cert_auth_info_t info;

			info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
			if (info == NULL)
				return GNUTLS_E_INTERNAL_ERROR;

			return info->dh.secret_bits;
		}
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}
}
Exemple #15
0
/**
 * gnutls_certificate_get_peers:
 * @session: is a gnutls session
 * @list_size: is the length of the certificate list
 *
 * Get 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.
 *
 * In case of OpenPGP keys a single key will be returned in raw
 * format.
 *
 * Returns: a pointer to a #gnutls_datum_t containing our
 *   certificates, or %NULL in case of an error or if no certificate
 *   was used.
 **/
const gnutls_datum_t *gnutls_certificate_get_peers(gnutls_session_t
						   session,
						   unsigned int *list_size)
{
	cert_auth_info_t info;

	CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, NULL);

	info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
	if (info == NULL)
		return NULL;

	*list_size = info->ncerts;
	return info->raw_certificate_list;
}
Exemple #16
0
static int
unpack_anon_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  int ret;
  size_t pack_size;
  anon_auth_info_t info = NULL;

  BUFFER_POP_NUM (ps, pack_size);

  if (pack_size == 0)
    return 0;                   /* nothing to be done */

  /* client and server have the same auth_info here
   */
  ret =
    _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
                           sizeof (anon_auth_info_st), 1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  BUFFER_POP_NUM (ps, info->dh.secret_bits);

  BUFFER_POP_DATUM (ps, &info->dh.prime);
  BUFFER_POP_DATUM (ps, &info->dh.generator);
  BUFFER_POP_DATUM (ps, &info->dh.public_key);

  return 0;

error:
  if (info)
    {
      _gnutls_free_datum (&info->dh.prime);
      _gnutls_free_datum (&info->dh.generator);
      _gnutls_free_datum (&info->dh.public_key);
    }

  return ret;
}
Exemple #17
0
/**
 * gnutls_psk_server_get_username - return the username of the peer
 * @session: is a gnutls session
 *
 * This should only be called in case of PSK authentication and in
 * case of a server.
 *
 * Returns: the username of the peer, or %NULL in case of an error.
 **/
const char *
gnutls_psk_server_get_username (gnutls_session_t session)
{
  psk_auth_info_t info;

  CHECK_AUTH (GNUTLS_CRD_PSK, NULL);

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    return NULL;

  if (info->username[0] != 0)
    return info->username;

  return NULL;
}
Exemple #18
0
/**
 * gnutls_psk_client_get_hint - return the PSK identity hint of the peer
 * @session: is a gnutls session
 *
 * The PSK identity hint may give the client help in deciding which
 * username to use.  This should only be called in case of PSK
 * authentication and in case of a client.
 *
 * Returns: the identity hint of the peer, or %NULL in case of an error.
 *
 * Since: 2.4.0
 **/
const char *
gnutls_psk_client_get_hint (gnutls_session_t session)
{
  psk_auth_info_t info;

  CHECK_AUTH (GNUTLS_CRD_PSK, NULL);

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    return NULL;

  if (info->hint[0] != 0)
    return info->hint;

  return NULL;
}
Exemple #19
0
/**
 * gnutls_certificate_get_peers_subkey_id:
 * @session: is a gnutls session
 * @id: will contain the ID
 *
 * Get the peer's subkey ID when OpenPGP certificates are
 * used. The returned @id should be treated as constant.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
 *   an error code is returned.
 *
 * Since: 3.1.3
 **/
int gnutls_certificate_get_peers_subkey_id(gnutls_session_t session,
					   gnutls_datum_t * id)
{
	cert_auth_info_t info;

	CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);

	info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
	if (info == NULL)
		return GNUTLS_E_INVALID_REQUEST;

	id->data = info->subkey_id;
	id->size = GNUTLS_OPENPGP_KEYID_SIZE;

	return 0;
}
Exemple #20
0
/* if the peer's certificate is of 512 bits or less, returns non zero.
 */
int
_gnutls_peers_cert_less_512 (gnutls_session_t session)
{
  gnutls_cert peer_cert;
  int ret;
  cert_auth_info_t info = _gnutls_get_auth_info (session);

  if (info == NULL || info->ncerts == 0)
    {
      gnutls_assert ();
      /* we need this in order to get peer's certificate */
      return 0;
    }

  if ((ret =
       _gnutls_get_auth_info_gcert (&peer_cert,
				    session->security_parameters.cert_type,
				    info, CERT_NO_COPY)) < 0)
    {
      gnutls_assert ();
      return 0;
    }

  if (peer_cert.subject_pk_algorithm != GNUTLS_PK_RSA)
    {
      gnutls_assert ();
      _gnutls_gcert_deinit (&peer_cert);
      return 0;
    }

  if (_gnutls_mpi_get_nbits (peer_cert.params[0]) <= 512)
    {
      _gnutls_gcert_deinit (&peer_cert);
      return 1;
    }

  _gnutls_gcert_deinit (&peer_cert);

  return 0;
}
Exemple #21
0
/* if the peer's certificate is of 512 bits or less, returns non zero.
 */
int
_gnutls_peers_cert_less_512 (gnutls_session_t session)
{
  gnutls_pcert_st peer_cert;
  int ret;
  cert_auth_info_t info = _gnutls_get_auth_info (session);

  if (info == NULL || info->ncerts == 0)
    {
      gnutls_assert ();
      /* we need this in order to get peer's certificate */
      return 0;
    }

  if ((ret =
       _gnutls_get_auth_info_pcert (&peer_cert,
                                    session->security_parameters.cert_type,
                                    info)) < 0)
    {
      gnutls_assert ();
      return 0;
    }

  if (gnutls_pubkey_get_pk_algorithm(peer_cert.pubkey, NULL) != GNUTLS_PK_RSA)
    {
      gnutls_assert ();
      gnutls_pcert_deinit (&peer_cert);
      return 0;
    }

  if (_gnutls_pubkey_is_over_rsa_512(peer_cert.pubkey) < 0)
    {
      gnutls_pcert_deinit (&peer_cert);
      return 1;
    }

  gnutls_pcert_deinit (&peer_cert);

  return 0;
}
Exemple #22
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the SRP username (x)
 *      x bytes the SRP username
 */
static int
pack_srp_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
{
  srp_server_auth_info_t info = _gnutls_get_auth_info (session);
  int pack_size;

  if (info == NULL && session->key->auth_info_size != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (info && info->username)
    pack_size = strlen (info->username) + 1;	/* include the terminating null */
  else
    pack_size = 0;

  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);

  /* calculate the size and allocate the data.
   */
  packed_session->data =
    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);

  if (packed_session->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  packed_session->data[0] = GNUTLS_CRD_SRP;
  _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);

  if (pack_size > 0)
    memcpy (&packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
	    info->username, pack_size + 1);

  return 0;
}
Exemple #23
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *
 *      4 bytes the size of the PSK username (x)
 *      x bytes the PSK username
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 */
static int
pack_psk_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  psk_auth_info_t info;
  int username_len;
  int hint_len, ret;
  int size_offset;
  size_t cur_size;

  info = _gnutls_get_auth_info (session);

  if (info && info->username)
    username_len = strlen (info->username) + 1; /* include the terminating null */
  else
    username_len = 0;

  if (info && info->hint)
    hint_len = strlen (info->hint) + 1; /* include the terminating null */
  else
    hint_len = 0;

  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;

  BUFFER_APPEND_PFX (ps, info->username, username_len);
  BUFFER_APPEND_PFX (ps, info->hint, hint_len);

  BUFFER_APPEND_NUM (ps, info->dh.secret_bits);
  BUFFER_APPEND_PFX (ps, info->dh.prime.data, info->dh.prime.size);
  BUFFER_APPEND_PFX (ps, info->dh.generator.data, info->dh.generator.size);
  BUFFER_APPEND_PFX (ps, info->dh.public_key.data, info->dh.public_key.size);

  /* write the real size */
  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}
Exemple #24
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *        DH stuff
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 *        RSA stuff
 *      4 bytes the size of the modulus
 *      x bytes the modulus
 *      4 bytes the size of the exponent
 *      x bytes the exponent
 *        CERTIFICATES
 *      4 bytes the length of the certificate list
 *      4 bytes the size of first certificate
 *      x bytes the certificate
 *       and so on...
 */
static int
pack_certificate_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  unsigned int i;
  int cur_size, ret;
  cert_auth_info_t info = _gnutls_get_auth_info (session);
  int size_offset;

  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;

  if (info)
    {

      BUFFER_APPEND_NUM (ps, info->dh.secret_bits);
      BUFFER_APPEND_PFX (ps, info->dh.prime.data, info->dh.prime.size);
      BUFFER_APPEND_PFX (ps, info->dh.generator.data,
                         info->dh.generator.size);
      BUFFER_APPEND_PFX (ps, info->dh.public_key.data,
                         info->dh.public_key.size);
      BUFFER_APPEND_PFX (ps, info->rsa_export.modulus.data,
                         info->rsa_export.modulus.size);
      BUFFER_APPEND_PFX (ps, info->rsa_export.exponent.data,
                         info->rsa_export.exponent.size);

      BUFFER_APPEND_NUM (ps, info->ncerts);

      for (i = 0; i < info->ncerts; i++)
        BUFFER_APPEND_PFX (ps, info->raw_certificate_list[i].data,
                           info->raw_certificate_list[i].size);
    }

  /* write the real size */
  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}
Exemple #25
0
static int
unpack_srp_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  size_t username_size;
  int ret;
  srp_server_auth_info_t info;

  BUFFER_POP_NUM (ps, username_size);
  if (username_size > sizeof (info->username))
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }


  ret =
    _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
                           sizeof (srp_server_auth_info_st), 1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  BUFFER_POP (ps, info->username, username_size);

  ret = 0;

error:
  return ret;
}
Exemple #26
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the SRP username (x)
 *      x bytes the SRP username
 */
static int
pack_srp_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  srp_server_auth_info_t info = _gnutls_get_auth_info (session);
  int len, ret;
  int size_offset;
  size_t cur_size;

  if (info && info->username)
    len = strlen (info->username) + 1;  /* include the terminating null */
  else
    len = 0;

  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;

  BUFFER_APPEND_PFX (ps, info->username, len);

  /* write the real size */
  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}
Exemple #27
0
static int
proc_dhe_server_kx (gnutls_session_t session, opaque * data,
                    size_t _data_size)
{
  int sigsize;
  opaque *sigdata;
  gnutls_datum_t vparams, signature;
  int ret;
  cert_auth_info_t info = _gnutls_get_auth_info (session);
  ssize_t data_size = _data_size;
  gnutls_cert peer_cert;
  gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

  if (info == NULL || info->ncerts == 0)
    {
      gnutls_assert ();
      /* we need this in order to get peer's certificate */
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* VERIFY SIGNATURE */

  vparams.size = ret;
  vparams.data = data;

  sigdata = &data[vparams.size];
  if (_gnutls_version_has_selectable_sighash (ver))
    {
      sign_algorithm_st aid;

      DECR_LEN (data_size, 1);
      aid.hash_algorithm = *sigdata++;
      DECR_LEN (data_size, 1);
      aid.sign_algorithm = *sigdata++;
      sign_algo = _gnutls_tls_aid_to_sign (&aid);
      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
        {
          gnutls_assert ();
          return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
        }
    }
  DECR_LEN (data_size, 2);
  sigsize = _gnutls_read_uint16 (sigdata);
  sigdata += 2;

  DECR_LEN (data_size, sigsize);
  signature.data = sigdata;
  signature.size = sigsize;

  if ((ret =
       _gnutls_get_auth_info_gcert (&peer_cert,
                                    session->security_parameters.cert_type,
                                    info, CERT_NO_COPY)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ret =
    _gnutls_handshake_verify_data (session, &peer_cert, &vparams, &signature,
                                   sign_algo);

  _gnutls_gcert_deinit (&peer_cert);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return ret;
}
Exemple #28
0
static int
proc_psk_client_kx (gnutls_session_t session, opaque * data,
		    size_t _data_size)
{
  int bits;
  int ret;
  mpi_t p, g;
  gnutls_dh_params_t dh_params;
  const mpi_t *mpis;
  gnutls_psk_server_credentials_t cred;
  psk_auth_info_t info;
  gnutls_datum_t username;
  ssize_t data_size = _data_size;

  cred = (gnutls_psk_server_credentials_t)
    _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL);

  if (cred == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  bits = _gnutls_dh_get_allowed_prime_bits (session);

  if ((ret =
       _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
			      sizeof (psk_auth_info_st), 1)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  dh_params =
    _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
  mpis = _gnutls_dh_params_to_mpi (dh_params);
  if (mpis == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
    }

  p = mpis[0];
  g = mpis[1];

  DECR_LEN (data_size, 2);
  username.size = _gnutls_read_uint16 (&data[0]);

  DECR_LEN (data_size, username.size);

  username.data = &data[2];

  /* copy the username to the auth info structures
   */
  info = _gnutls_get_auth_info (session);

  if (username.size > MAX_SRP_USERNAME)
    {
      gnutls_assert ();
      return GNUTLS_E_ILLEGAL_SRP_USERNAME;
    }

  memcpy (info->username, username.data, username.size);
  info->username[username.size] = 0;

  /* Adjust the data */
  data += username.size + 2;

  ret = _gnutls_proc_dh_common_client_kx (session, data, data_size, g, p);

  return ret;

}
Exemple #29
0
/* Send the first key exchange message ( g, n, s) and append the verifier algorithm number 
 * Data is allocated by the caller, and should have data_size size.
 */
int
_gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data)
{
  int ret;
  uint8_t *data_n, *data_s;
  uint8_t *data_g;
  char *username;
  SRP_PWD_ENTRY *pwd_entry;
  srp_server_auth_info_t info;
  ssize_t data_size;
  size_t n_b, tmp_size;
  char buf[64];
  uint8_t *data_b;

  if ((ret =
       _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
			      sizeof (srp_server_auth_info_st), 1)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  username = info->username;

  _gnutls_str_cpy (username, MAX_SRP_USERNAME,
		   session->security_parameters.extensions.srp_username);

  ret = _gnutls_srp_pwd_read_entry (session, username, &pwd_entry);

  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* copy from pwd_entry to local variables (actually in session) */
  tmp_size = pwd_entry->g.size;
  if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, &tmp_size) < 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  tmp_size = pwd_entry->n.size;
  if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, &tmp_size) < 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  tmp_size = pwd_entry->v.size;
  if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, &tmp_size) < 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  /* Calculate:  B = (k*v + g^b) % N 
   */
  B = _gnutls_calc_srp_B (&_b, G, N, V);
  if (B == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  if (_gnutls_mpi_print (NULL, &n_b, B) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_PRINT_FAILED;
    }


  /* Allocate size to hold the N, g, s, B 
   */

  data_size = (pwd_entry->n.size + 2 + pwd_entry->g.size + 2 +
	       pwd_entry->salt.size + 1) + (n_b + 2);

  (*data) = gnutls_malloc (data_size);
  if ((*data) == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* copy N (mod n) 
   */
  data_n = *data;
  _gnutls_write_datum16 (data_n, pwd_entry->n);


  /* copy G (generator) to data 
   */
  data_g = &data_n[2 + pwd_entry->n.size];
  _gnutls_write_datum16 (data_g, pwd_entry->g);


  /* copy the salt 
   */
  data_s = &data_g[2 + pwd_entry->g.size];
  _gnutls_write_datum8 (data_s, pwd_entry->salt);


  /* Copy the B value
   */

  data_b = &data_s[1 + pwd_entry->salt.size];
  if (_gnutls_mpi_print (&data_b[2], &n_b, B) != 0) 
    {
      gnutls_assert();
      return GNUTLS_E_MPI_PRINT_FAILED;
    }

  _gnutls_write_uint16 (n_b, data_b);

  _gnutls_hard_log ("INT: SRP B[%d]: %s\n", n_b,
		    _gnutls_bin2hex (&data_b[2], n_b, buf, sizeof (buf)));

  _gnutls_srp_entry_free (pwd_entry);

  return data_size;
}
Exemple #30
0
/*-
 * _gnutls_free_auth_info - Frees the auth info structure
 * @session: is a #gnutls_session_t structure.
 *
 * This function frees the auth info structure and sets it to
 * null. It must be called since some structures contain malloced
 * elements.
 -*/
void _gnutls_free_auth_info(gnutls_session_t session)
{
	dh_info_st *dh_info;

	if (session == NULL) {
		gnutls_assert();
		return;
	}

	switch (session->key.auth_info_type) {
	case GNUTLS_CRD_SRP:
		break;
	case GNUTLS_CRD_ANON:
		{
			anon_auth_info_t info =
			    _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);

			if (info == NULL)
				break;

			dh_info = &info->dh;
			_gnutls_free_dh_info(dh_info);
		}
		break;
	case GNUTLS_CRD_PSK:
		{
			psk_auth_info_t info =
			    _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);

			if (info == NULL)
				break;

			dh_info = &info->dh;
			_gnutls_free_dh_info(dh_info);
		}
		break;
	case GNUTLS_CRD_CERTIFICATE:
		{
			unsigned int i;
			cert_auth_info_t info =
			    _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);

			if (info == NULL)
				break;

			dh_info = &info->dh;
			for (i = 0; i < info->ncerts; i++) {
				_gnutls_free_datum(&info->
						   raw_certificate_list
						   [i]);
			}

			gnutls_free(info->raw_certificate_list);
			info->raw_certificate_list = NULL;
			info->ncerts = 0;

			_gnutls_free_dh_info(dh_info);
		}


		break;
	default:
		return;

	}

	gnutls_free(session->key.auth_info);
	session->key.auth_info = NULL;
	session->key.auth_info_size = 0;
	session->key.auth_info_type = 0;

}