Ejemplo n.º 1
0
int _gnutls_ecdh_generate_key(gnutls_ecc_curve_t curve,
			      gnutls_datum_t *x, gnutls_datum_t *y,
			      gnutls_datum_t *k)
{
	gnutls_pk_params_st params;
	int ret;

	gnutls_pk_params_init(&params);
	params.flags = curve;
	params.algo = GNUTLS_PK_EC;

	x->data = NULL;
	y->data = NULL;
	k->data = NULL;

	ret = _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve, &params);
	if (ret < 0) {
		return gnutls_assert_val(ret);
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[ECC_X], x);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[ECC_Y], y);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[ECC_K], k);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret = 0;
	goto cleanup;
 fail:
 	gnutls_free(y->data);
 	gnutls_free(x->data);
 	gnutls_free(k->data);
 cleanup:
 	gnutls_pk_params_clear(&params);
 	return ret;
}
Ejemplo n.º 2
0
int _gnutls_params_get_ecc_raw(const gnutls_pk_params_st* params,
				       gnutls_ecc_curve_t * curve,
				       gnutls_datum_t * x,
				       gnutls_datum_t * y,
				       gnutls_datum_t * k)
{
	int ret;

	if (params == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (curve)
		*curve = params->flags;

	/* X */
	if (x) {
		ret = _gnutls_mpi_dprint_lz(params->params[ECC_X], x);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}
	}

	/* Y */
	if (y) {
		ret = _gnutls_mpi_dprint_lz(params->params[ECC_Y], y);
		if (ret < 0) {
			gnutls_assert();
			_gnutls_free_datum(x);
			return ret;
		}
	}


	/* K */
	if (k) {
		ret = _gnutls_mpi_dprint_lz(params->params[ECC_K], k);
		if (ret < 0) {
			gnutls_assert();
			_gnutls_free_datum(x);
			_gnutls_free_datum(y);
			return ret;
		}
	}

	return 0;

}
Ejemplo n.º 3
0
/**
 * gnutls_x509_privkey_export_ecc_raw:
 * @key: a structure that holds the rsa parameters
 * @curve: will hold the curve
 * @x: will hold the x coordinate
 * @y: will hold the y coordinate
 * @k: will hold the private key
 *
 * This function will export the ECC private key's parameters found
 * in the given structure. The new parameters will be allocated using
 * gnutls_malloc() and will be stored in the appropriate datum.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.0
 **/
int gnutls_x509_privkey_export_ecc_raw (gnutls_x509_privkey_t key, 
                                        gnutls_ecc_curve_t *curve,  
                                        gnutls_datum_t * x, gnutls_datum_t * y,
                                        gnutls_datum_t* k)
{
  int ret;

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  *curve = key->params.flags;

  /* X */
  ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_X], x);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* Y */
  ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_Y], y);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_free_datum (x);
      return ret;
    }


  /* K */
  ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_K], k);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_free_datum (x);
      _gnutls_free_datum (y);
      return ret;
    }

  return 0;

}
Ejemplo n.º 4
0
int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params,
			    gnutls_datum_t *priv_key, gnutls_datum_t *pub_key)
{
	gnutls_pk_params_st params;
	int ret;

	gnutls_pk_params_init(&params);
	params.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]);
	params.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]);

	params.params_nr = 3; /* include empty q */
	params.algo = GNUTLS_PK_DH;

	priv_key->data = NULL;
	pub_key->data = NULL;

	ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0, &params);
	if (ret < 0) {
		return gnutls_assert_val(ret);
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[DH_X], priv_key);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret =
	    _gnutls_mpi_dprint_lz(params.params[DH_Y], pub_key);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	ret = 0;
	goto cleanup;
 fail:
 	gnutls_free(pub_key->data);
 	gnutls_free(priv_key->data);
 cleanup:
 	gnutls_pk_params_clear(&params);
 	return ret;
}
Ejemplo n.º 5
0
int _gnutls_buffer_append_mpi (gnutls_buffer_st * buf, int pfx_size, bigint_t mpi, int lz)
{
gnutls_datum_t dd;
int ret;

  if (lz)
    ret = _gnutls_mpi_dprint_lz (mpi, &dd);
  else
    ret = _gnutls_mpi_dprint (mpi, &dd);

  if (ret < 0)
    return gnutls_assert_val(ret);

  ret = _gnutls_buffer_append_data_prefix(buf, pfx_size, dd.data, dd.size);
  
  _gnutls_free_datum(&dd);
  
  return ret;
}
Ejemplo n.º 6
0
/**
 * gnutls_x509_privkey_export_dsa_raw:
 * @key: a structure that holds the DSA parameters
 * @p: will hold the p
 * @q: will hold the q
 * @g: will hold the g
 * @y: will hold the y
 * @x: will hold the x
 *
 * This function will export the DSA private key's parameters found
 * in the given structure. The new parameters will be allocated using
 * gnutls_malloc() and will be stored in the appropriate datum.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
                                    gnutls_datum_t * p, gnutls_datum_t * q,
                                    gnutls_datum_t * g, gnutls_datum_t * y,
                                    gnutls_datum_t * x)
{
  int ret;

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* P */
  ret = _gnutls_mpi_dprint_lz (key->params.params[0], p);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* Q */
  ret = _gnutls_mpi_dprint_lz (key->params.params[1], q);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_free_datum (p);
      return ret;
    }


  /* G */
  ret = _gnutls_mpi_dprint_lz (key->params.params[2], g);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_free_datum (p);
      _gnutls_free_datum (q);
      return ret;
    }


  /* Y */
  ret = _gnutls_mpi_dprint_lz (key->params.params[3], y);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_free_datum (p);
      _gnutls_free_datum (g);
      _gnutls_free_datum (q);
      return ret;
    }

  /* X */
  ret = _gnutls_mpi_dprint_lz (key->params.params[4], x);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_free_datum (y);
      _gnutls_free_datum (p);
      _gnutls_free_datum (g);
      _gnutls_free_datum (q);
      return ret;
    }

  return 0;
}
Ejemplo n.º 7
0
/**
 * gnutls_x509_privkey_export_rsa_raw2:
 * @key: a structure that holds the rsa parameters
 * @m: will hold the modulus
 * @e: will hold the public exponent
 * @d: will hold the private exponent
 * @p: will hold the first prime (p)
 * @q: will hold the second prime (q)
 * @u: will hold the coefficient
 * @e1: will hold e1 = d mod (p-1)
 * @e2: will hold e2 = d mod (q-1)
 *
 * This function will export the RSA private key's parameters found
 * in the given structure. The new parameters will be allocated using
 * gnutls_malloc() and will be stored in the appropriate datum.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.12.0
 **/
int
gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
                                     gnutls_datum_t * m, gnutls_datum_t * e,
                                     gnutls_datum_t * d, gnutls_datum_t * p,
                                     gnutls_datum_t * q, gnutls_datum_t * u,
                                     gnutls_datum_t * e1, gnutls_datum_t * e2)
{
  int ret;
  gnutls_pk_params_st pk_params;
  
  gnutls_pk_params_init(&pk_params);

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  m->data = e->data = d->data = p->data = q->data = u->data = NULL;
  m->size = e->size = d->size = p->size = q->size = u->size = 0;

  ret = _gnutls_pk_params_copy (&pk_params, &key->params);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  ret = _gnutls_mpi_dprint_lz (pk_params.params[0], m);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  /* E */
  ret = _gnutls_mpi_dprint_lz (pk_params.params[1], e);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  /* D */
  ret = _gnutls_mpi_dprint_lz (pk_params.params[2], d);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  /* P */
  ret = _gnutls_mpi_dprint_lz (pk_params.params[3], p);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  /* Q */
  ret = _gnutls_mpi_dprint_lz (pk_params.params[4], q);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  /* U */
  ret = _gnutls_mpi_dprint_lz (key->params.params[5], u);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  /* E1 */
  if (e1)
    {
      ret = _gnutls_mpi_dprint_lz (key->params.params[6], e1);
      if (ret < 0)
        {
          gnutls_assert ();
          goto error;
        }
    }

  /* E2 */
  if (e2)
    {
      ret = _gnutls_mpi_dprint_lz (key->params.params[7], e2);
      if (ret < 0)
        {
          gnutls_assert ();
          goto error;
        }
    }

  gnutls_pk_params_release (&pk_params);

  return 0;

error:
  _gnutls_free_datum (m);
  _gnutls_free_datum (d);
  _gnutls_free_datum (e);
  _gnutls_free_datum (p);
  _gnutls_free_datum (q);
  gnutls_pk_params_release (&pk_params);

  return ret;
}
Ejemplo n.º 8
0
Archivo: privkey.c Proyecto: sqs/gnutls
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
 */
static int
_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params)
{
  int result;
  opaque null = '\0';
  gnutls_pk_params_st pk_params;
  gnutls_datum_t m, e, d, p, q, u, exp1, exp2;

  memset (&pk_params, 0, sizeof (pk_params));

  memset (&m, 0, sizeof (m));
  memset (&p, 0, sizeof (e));
  memset (&q, 0, sizeof (d));
  memset (&p, 0, sizeof (p));
  memset (&q, 0, sizeof (q));
  memset (&u, 0, sizeof (u));
  memset (&exp1, 0, sizeof (exp1));
  memset (&exp2, 0, sizeof (exp2));

  result = _gnutls_pk_params_copy (&pk_params, params, RSA_PRIVATE_PARAMS);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  /* retrieve as data */

  result = _gnutls_mpi_dprint_lz (pk_params.params[0], &m);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_mpi_dprint_lz (pk_params.params[1], &e);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_mpi_dprint_lz (pk_params.params[2], &d);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_mpi_dprint_lz (pk_params.params[3], &p);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_mpi_dprint_lz (pk_params.params[4], &q);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_mpi_dprint_lz (pk_params.params[5], &u);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_mpi_dprint_lz (pk_params.params[6], &exp1);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result = _gnutls_mpi_dprint_lz (pk_params.params[7], &exp2);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  /* Ok. Now we have the data. Create the asn1 structures
   */

  /* first make sure that no previously allocated data are leaked */
  if (*c2 != ASN1_TYPE_EMPTY)
    {
      asn1_delete_structure (c2);
      *c2 = ASN1_TYPE_EMPTY;
    }

  if ((result = asn1_create_element
       (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", c2))
      != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Write PRIME 
   */
  if ((result = asn1_write_value (*c2, "modulus",
                                  m.data, m.size)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "publicExponent",
                                  e.data, e.size)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "privateExponent",
                                  d.data, d.size)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "prime1",
                                  p.data, p.size)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "prime2",
                                  q.data, q.size)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "coefficient",
                                  u.data, u.size)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);

      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "exponent1",
                                  exp1.data, exp1.size)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "exponent2",
                                  exp2.data, exp2.size)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "otherPrimeInfos",
                                  NULL, 0)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  result = 0;

cleanup:
  if (result != 0)
    asn1_delete_structure (c2);

  gnutls_pk_params_release (&pk_params);

  _gnutls_free_datum (&m);
  _gnutls_free_datum (&d);
  _gnutls_free_datum (&e);
  _gnutls_free_datum (&p);
  _gnutls_free_datum (&q);
  _gnutls_free_datum (&u);
  _gnutls_free_datum (&exp1);
  _gnutls_free_datum (&exp2);

  return result;
}
Ejemplo n.º 9
0
int
_gnutls_params_get_dsa_raw(const gnutls_pk_params_st* params,
			     gnutls_datum_t * p, gnutls_datum_t * q,
			     gnutls_datum_t * g, gnutls_datum_t * y,
			     gnutls_datum_t * x)
{
	int ret;

	if (params == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (params->algo != GNUTLS_PK_DSA) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	/* P */
	if (p) {
		ret = _gnutls_mpi_dprint_lz(params->params[0], p);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}
	}

	/* Q */
	if (q) {
		ret = _gnutls_mpi_dprint_lz(params->params[1], q);
		if (ret < 0) {
			gnutls_assert();
			_gnutls_free_datum(p);
			return ret;
		}
	}


	/* G */
	if (g) {
		ret = _gnutls_mpi_dprint_lz(params->params[2], g);
		if (ret < 0) {
			gnutls_assert();
			_gnutls_free_datum(p);
			_gnutls_free_datum(q);
			return ret;
		}
	}


	/* Y */
	if (y) {
		ret = _gnutls_mpi_dprint_lz(params->params[3], y);
		if (ret < 0) {
			gnutls_assert();
			_gnutls_free_datum(p);
			_gnutls_free_datum(g);
			_gnutls_free_datum(q);
			return ret;
		}
	}

	/* X */
	if (x) {
		ret = _gnutls_mpi_dprint_lz(params->params[4], x);
		if (ret < 0) {
			gnutls_assert();
			_gnutls_free_datum(y);
			_gnutls_free_datum(p);
			_gnutls_free_datum(g);
			_gnutls_free_datum(q);
			return ret;
		}
	}

	return 0;
}
Ejemplo n.º 10
0
int
_gnutls_params_get_rsa_raw(const gnutls_pk_params_st* params,
				    gnutls_datum_t * m, gnutls_datum_t * e,
				    gnutls_datum_t * d, gnutls_datum_t * p,
				    gnutls_datum_t * q, gnutls_datum_t * u,
				    gnutls_datum_t * e1,
				    gnutls_datum_t * e2)
{
	int ret;

	if (params == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (params->algo != GNUTLS_PK_RSA) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (m) {
		ret = _gnutls_mpi_dprint_lz(params->params[0], m);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	}

	/* E */
	if (e) {
		ret = _gnutls_mpi_dprint_lz(params->params[1], e);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	}

	/* D */
	if (d && params->params[2]) {
		ret = _gnutls_mpi_dprint_lz(params->params[2], d);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (d) {
		d->data = NULL;
		d->size = 0;
	}

	/* P */
	if (p && params->params[3]) {
		ret = _gnutls_mpi_dprint_lz(params->params[3], p);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (p) {
		p->data = NULL;
		p->size = 0;
	}

	/* Q */
	if (q && params->params[4]) {
		ret = _gnutls_mpi_dprint_lz(params->params[4], q);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (q) {
		q->data = NULL;
		q->size = 0;
	}

	/* U */
	if (u && params->params[5]) {
		ret = _gnutls_mpi_dprint_lz(params->params[5], u);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (u) {
		u->data = NULL;
		u->size = 0;
	}

	/* E1 */
	if (e1 && params->params[6]) {
		ret = _gnutls_mpi_dprint_lz(params->params[6], e1);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (e1) {
		e1->data = NULL;
		e1->size = 0;
	}

	/* E2 */
	if (e2 && params->params[7]) {
		ret = _gnutls_mpi_dprint_lz(params->params[7], e2);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (e2) {
		e2->data = NULL;
		e2->size = 0;
	}

	return 0;

      error:
	_gnutls_free_datum(m);
	_gnutls_free_datum(d);
	_gnutls_free_datum(e);
	_gnutls_free_datum(e1);
	_gnutls_free_datum(e2);
	_gnutls_free_datum(p);
	_gnutls_free_datum(q);

	return ret;
}
Ejemplo n.º 11
0
/**
 * gnutls_pkcs11_copy_x509_privkey:
 * @token_url: A PKCS #11 URL specifying a token
 * @key: A private key
 * @label: A name to be used for the stored data
 * @key_usage: One of GNUTLS_KEY_*
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
 *
 * This function will copy a private key into a PKCS #11 token specified by
 * a URL. It is highly recommended flags to contain %GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE
 * unless there is a strong reason not to.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.12.0
 **/
int
gnutls_pkcs11_copy_x509_privkey(const char *token_url,
				gnutls_x509_privkey_t key,
				const char *label,
				unsigned int key_usage, unsigned int flags)
{
	int ret;
	struct p11_kit_uri *info = NULL;
	ck_rv_t rv;
	size_t id_size;
	uint8_t id[20];
	struct ck_attribute a[16];
	ck_object_class_t class = CKO_PRIVATE_KEY;
	ck_object_handle_t obj;
	ck_key_type_t type;
	int a_val;
	gnutls_pk_algorithm_t pk;
	gnutls_datum_t p, q, g, y, x;
	gnutls_datum_t m, e, d, u, exp1, exp2;
	struct pkcs11_session_info sinfo;

	PKCS11_CHECK_INIT;

	memset(&sinfo, 0, sizeof(sinfo));

	memset(&p, 0, sizeof(p));
	memset(&q, 0, sizeof(q));
	memset(&g, 0, sizeof(g));
	memset(&y, 0, sizeof(y));
	memset(&x, 0, sizeof(x));
	memset(&m, 0, sizeof(m));
	memset(&e, 0, sizeof(e));
	memset(&d, 0, sizeof(d));
	memset(&u, 0, sizeof(u));
	memset(&exp1, 0, sizeof(exp1));
	memset(&exp2, 0, sizeof(exp2));

	ret = pkcs11_url_to_info(token_url, &info);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	id_size = sizeof(id);
	ret = gnutls_x509_privkey_get_key_id(key, 0, id, &id_size);
	if (ret < 0) {
		p11_kit_uri_free(info);
		gnutls_assert();
		return ret;
	}

	ret =
	    pkcs11_open_session(&sinfo, NULL, info,
				SESSION_WRITE |
				pkcs11_obj_flags_to_int(flags));
	p11_kit_uri_free(info);

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

	/* FIXME: copy key usage flags */
	a_val = 0;
	a[a_val].type = CKA_CLASS;
	a[a_val].value = &class;
	a[a_val].value_len = sizeof(class);
	a_val++;

	a[a_val].type = CKA_ID;
	a[a_val].value = id;
	a[a_val].value_len = id_size;
	a_val++;

	a[a_val].type = CKA_KEY_TYPE;
	a[a_val].value = &type;
	a[a_val].value_len = sizeof(type);
	a_val++;

	a[a_val].type = CKA_TOKEN;
	a[a_val].value = (void *) &tval;
	a[a_val].value_len = sizeof(tval);
	a_val++;

	/* a private key is set always as private unless
	 * requested otherwise
	 */
	if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE) {
		a[a_val].type = CKA_PRIVATE;
		a[a_val].value = (void *) &fval;
		a[a_val].value_len = sizeof(fval);
		a_val++;
	} else {
		a[a_val].type = CKA_PRIVATE;
		a[a_val].value = (void *) &tval;
		a[a_val].value_len = sizeof(tval);
		a_val++;
	}

	if (label) {
		a[a_val].type = CKA_LABEL;
		a[a_val].value = (void *) label;
		a[a_val].value_len = strlen(label);
		a_val++;
	}

	if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE) {
		a[a_val].type = CKA_SENSITIVE;
		a[a_val].value = (void *) &tval;
		a[a_val].value_len = sizeof(tval);
		a_val++;
	} else {
		a[a_val].type = CKA_SENSITIVE;
		a[a_val].value = (void *) &fval;
		a[a_val].value_len = sizeof(fval);
		a_val++;
	}

	pk = gnutls_x509_privkey_get_pk_algorithm(key);
	switch (pk) {
	case GNUTLS_PK_RSA:
		{

			ret =
			    gnutls_x509_privkey_export_rsa_raw2(key, &m,
								&e, &d, &p,
								&q, &u,
								&exp1,
								&exp2);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}

			type = CKK_RSA;

			a[a_val].type = CKA_MODULUS;
			a[a_val].value = m.data;
			a[a_val].value_len = m.size;
			a_val++;

			a[a_val].type = CKA_PUBLIC_EXPONENT;
			a[a_val].value = e.data;
			a[a_val].value_len = e.size;
			a_val++;

			a[a_val].type = CKA_PRIVATE_EXPONENT;
			a[a_val].value = d.data;
			a[a_val].value_len = d.size;
			a_val++;

			a[a_val].type = CKA_PRIME_1;
			a[a_val].value = p.data;
			a[a_val].value_len = p.size;
			a_val++;

			a[a_val].type = CKA_PRIME_2;
			a[a_val].value = q.data;
			a[a_val].value_len = q.size;
			a_val++;

			a[a_val].type = CKA_COEFFICIENT;
			a[a_val].value = u.data;
			a[a_val].value_len = u.size;
			a_val++;

			a[a_val].type = CKA_EXPONENT_1;
			a[a_val].value = exp1.data;
			a[a_val].value_len = exp1.size;
			a_val++;

			a[a_val].type = CKA_EXPONENT_2;
			a[a_val].value = exp2.data;
			a[a_val].value_len = exp2.size;
			a_val++;

			break;
		}
	case GNUTLS_PK_DSA:
		{
			ret =
			    gnutls_x509_privkey_export_dsa_raw(key, &p, &q,
							       &g, &y, &x);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}

			type = CKK_DSA;

			a[a_val].type = CKA_PRIME;
			a[a_val].value = p.data;
			a[a_val].value_len = p.size;
			a_val++;

			a[a_val].type = CKA_SUBPRIME;
			a[a_val].value = q.data;
			a[a_val].value_len = q.size;
			a_val++;

			a[a_val].type = CKA_BASE;
			a[a_val].value = g.data;
			a[a_val].value_len = g.size;
			a_val++;

			a[a_val].type = CKA_VALUE;
			a[a_val].value = x.data;
			a[a_val].value_len = x.size;
			a_val++;

			break;
		}
	case GNUTLS_PK_EC:
		{
			ret =
			    _gnutls_x509_write_ecc_params(key->params.flags,
							  &p);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}

			ret =
			    _gnutls_mpi_dprint_lz(&key->params.
						  params[ECC_K], &x);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}

			type = CKK_ECDSA;

			a[a_val].type = CKA_EC_PARAMS;
			a[a_val].value = p.data;
			a[a_val].value_len = p.size;
			a_val++;

			a[a_val].type = CKA_VALUE;
			a[a_val].value = x.data;
			a[a_val].value_len = x.size;
			a_val++;

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

	rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &obj);
	if (rv != CKR_OK) {
		gnutls_assert();
		_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
		ret = pkcs11_rv_to_err(rv);
		goto cleanup;
	}

	ret = 0;

      cleanup:
	switch (pk) {
	case GNUTLS_PK_RSA:
		{
			gnutls_free(m.data);
			gnutls_free(e.data);
			gnutls_free(d.data);
			gnutls_free(p.data);
			gnutls_free(q.data);
			gnutls_free(u.data);
			gnutls_free(exp1.data);
			gnutls_free(exp2.data);
			break;
		}
	case GNUTLS_PK_DSA:
		{
			gnutls_free(p.data);
			gnutls_free(q.data);
			gnutls_free(g.data);
			gnutls_free(y.data);
			gnutls_free(x.data);
			break;
		}
	case GNUTLS_PK_EC:
		{
			gnutls_free(p.data);
			gnutls_free(x.data);
			break;
		}
	default:
		gnutls_assert();
		ret = GNUTLS_E_INVALID_REQUEST;
		break;
	}

	if (sinfo.pks != 0)
		pkcs11_close_session(&sinfo);

	return ret;

}