Exemplo n.º 1
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;
}
Exemplo n.º 2
0
/**
 * gnutls_certificate_free_keys:
 * @sc: is a #gnutls_certificate_credentials_t structure.
 *
 * This function will delete all the keys and the certificates associated
 * with the given credentials. This function must not be called when a
 * TLS negotiation that uses the credentials is in progress.
 *
 **/
void
gnutls_certificate_free_keys (gnutls_certificate_credentials_t sc)
{
  unsigned i, j;

  for (i = 0; i < sc->ncerts; i++)
    {
      for (j = 0; j < sc->certs[i].cert_list_length; j++)
        {
          gnutls_pcert_deinit (&sc->certs[i].cert_list[j]);
        }
      gnutls_free (sc->certs[i].cert_list);
      _gnutls_str_array_clear (&sc->certs[i].names);
    }

  gnutls_free (sc->certs);
  sc->certs = NULL;

  for (i = 0; i < sc->ncerts; i++)
    {
      gnutls_privkey_deinit (sc->pkey[i]);
    }

  gnutls_free (sc->pkey);
  sc->pkey = NULL;

  sc->ncerts = 0;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
void doit(void)
{
	server_check();
	reset_buffers();
	client_check();

	if (g_pcert) {
		gnutls_pcert_deinit(g_pcert);
		gnutls_free(g_pcert);
	}
	if (g_pkey) {
		gnutls_privkey_deinit(g_pkey);
	}
}
Exemplo n.º 5
0
static int
proc_rsa_export_server_kx (gnutls_session_t session,
                           opaque * data, size_t _data_size)
{
  uint16_t n_m, n_e;
  size_t _n_m, _n_e;
  uint8_t *data_m;
  uint8_t *data_e;
  int i, sigsize;
  gnutls_datum_t vparams, signature;
  int ret;
  ssize_t data_size = _data_size;
  cert_auth_info_t info;
  gnutls_pcert_st peer_cert;

  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 GNUTLS_E_INTERNAL_ERROR;
    }


  i = 0;

  DECR_LEN (data_size, 2);
  n_m = _gnutls_read_uint16 (&data[i]);
  i += 2;

  DECR_LEN (data_size, n_m);
  data_m = &data[i];
  i += n_m;

  DECR_LEN (data_size, 2);
  n_e = _gnutls_read_uint16 (&data[i]);
  i += 2;

  DECR_LEN (data_size, n_e);
  data_e = &data[i];
  i += n_e;

  _n_e = n_e;
  _n_m = n_m;

  if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, _n_m) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, _n_e) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  _gnutls_rsa_export_set_pubkey (session, session->key->rsa[1],
                                 session->key->rsa[0]);

  /* VERIFY SIGNATURE */

  vparams.size = n_m + n_e + 4;
  vparams.data = data;

  DECR_LEN (data_size, 2);
  sigsize = _gnutls_read_uint16 (&data[vparams.size]);

  DECR_LEN (data_size, sigsize);
  signature.data = &data[vparams.size + 2];
  signature.size = sigsize;

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

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

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

  return ret;
}
Exemplo n.º 6
0
static int
proc_srp_cert_server_kx(gnutls_session_t session, uint8_t * data,
			size_t _data_size)
{
	ssize_t ret;
	int sigsize;
	gnutls_datum_t vparams, signature;
	ssize_t data_size;
	cert_auth_info_t info;
	gnutls_pcert_st peer_cert;
	uint8_t *p;
	gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
	const version_entry_st *ver = get_version(session);

	if (unlikely(ver == NULL))
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	ret = _gnutls_proc_srp_server_kx(session, data, _data_size);
	if (ret < 0)
		return ret;

	data_size = _data_size - ret;

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

	/* VERIFY SIGNATURE */

	vparams.size = ret;	/* all the data minus the signature */
	vparams.data = data;

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

		DECR_LEN(data_size, 1);
		aid.hash_algorithm = *p++;
		DECR_LEN(data_size, 1);
		aid.sign_algorithm = *p++;
		sign_algo = _gnutls_tls_aid_to_sign(&aid);
		if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
			_gnutls_debug_log("unknown signature %d.%d\n",
					  aid.sign_algorithm,
					  aid.hash_algorithm);
			gnutls_assert();
			return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
		}
	}

	DECR_LEN(data_size, 2);
	sigsize = _gnutls_read_uint16(p);

	DECR_LEN(data_size, sigsize);
	signature.data = &p[2];
	signature.size = sigsize;

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

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

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

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

	return 0;
}
Exemplo n.º 7
0
Arquivo: dhe.c Projeto: intgr/gnutls
static int
proc_dhe_server_kx (gnutls_session_t session, uint8_t * data,
                    size_t _data_size)
{
  int sigsize;
  uint8_t *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_pcert_st 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;
    }

  if (!_gnutls_session_is_ecc (session))
    ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size);
  else
    ret = _gnutls_proc_ecdh_common_server_kx (session, data, _data_size);

  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_debug_log("unknown signature %d.%d\n", aid.sign_algorithm, aid.hash_algorithm);
          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_pcert (&peer_cert,
                                    session->security_parameters.cert_type,
                                    info)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

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

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

  return ret;
}
Exemplo n.º 8
0
/* Reads a base64 encoded certificate list from memory and stores it to
 * a gnutls_cert structure. Returns the number of certificate parsed.
 */
static int
parse_pem_cert_mem(gnutls_certificate_credentials_t res,
		   gnutls_privkey_t key,
		   const char *input_cert, int input_cert_size)
{
	int size;
	const char *ptr;
	gnutls_datum_t tmp;
	int ret, count, i;
	unsigned ncerts = 0;
	gnutls_pcert_st *pcerts = NULL;
	gnutls_str_array_t names;
	gnutls_x509_crt_t unsorted[DEFAULT_MAX_VERIFY_DEPTH];

	_gnutls_str_array_init(&names);

	/* move to the certificate
	 */
	ptr = memmem(input_cert, input_cert_size,
		     PEM_CERT_SEP, sizeof(PEM_CERT_SEP) - 1);
	if (ptr == NULL)
		ptr = memmem(input_cert, input_cert_size,
			     PEM_CERT_SEP2, sizeof(PEM_CERT_SEP2) - 1);

	if (ptr == NULL) {
		gnutls_assert();
		return GNUTLS_E_BASE64_DECODING_ERROR;
	}
	size = input_cert_size - (ptr - input_cert);

	count = 0;

	do {
		tmp.data = (void *) ptr;
		tmp.size = size;

		ret = gnutls_x509_crt_init(&unsorted[count]);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		ret = gnutls_x509_crt_import(unsorted[count], &tmp, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		count++;

		/* now we move ptr after the pem header
		 */
		ptr++;
		size--;

		/* find the next certificate (if any)
		 */

		if (size > 0) {
			char *ptr3;

			ptr3 =
			    memmem(ptr, size, PEM_CERT_SEP,
				   sizeof(PEM_CERT_SEP) - 1);
			if (ptr3 == NULL)
				ptr3 = memmem(ptr, size, PEM_CERT_SEP2,
					      sizeof(PEM_CERT_SEP2) - 1);

			ptr = ptr3;
			size = input_cert_size - (ptr - input_cert);
		} else
			ptr = NULL;

	}
	while (ptr != NULL && count < DEFAULT_MAX_VERIFY_DEPTH);

	ret =
	    _gnutls_get_x509_name(unsorted[0], &names);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * count);
	if (pcerts == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	ncerts = count;
	ret =
	    gnutls_pcert_import_x509_list(pcerts, unsorted, &ncerts, GNUTLS_X509_CRT_LIST_SORT);
	if (ret < 0) {
		gnutls_free(pcerts);
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_certificate_credential_append_keypair(res, key, names, pcerts, ncerts);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	for (i = 0; i < count; i++)
		gnutls_x509_crt_deinit(unsorted[i]);

	return ncerts;

      cleanup:
	_gnutls_str_array_clear(&names);
	for (i = 0; i < count; i++)
		gnutls_x509_crt_deinit(unsorted[i]);
	if (pcerts) {
		for (i = 0; i < count; i++)
			gnutls_pcert_deinit(&pcerts[i]);
		gnutls_free(pcerts);
	}
	return ret;
}