Exemple #1
0
/* Always has the first bit zero */
int
_gnutls_mpi_dprint_lz (const bigint_t a, gnutls_datum_t * dest)
{
  int ret;
  opaque *buf = NULL;
  size_t bytes = 0;

  if (dest == NULL || a == NULL)
    return GNUTLS_E_INVALID_REQUEST;

  _gnutls_mpi_print_lz (a, NULL, &bytes);

  if (bytes != 0)
    buf = gnutls_malloc (bytes);
  if (buf == NULL)
    return GNUTLS_E_MEMORY_ERROR;

  ret = _gnutls_mpi_print_lz (a, buf, &bytes);
  if (ret < 0)
    {
      gnutls_free (buf);
      return ret;
    }

  dest->data = buf;
  dest->size = bytes;
  return 0;
}
Exemple #2
0
/* Writes the specified integer into the specified node.
 */
int
_gnutls_x509_write_int (ASN1_TYPE node, const char *value, bigint_t mpi,
                        int lz)
{
  opaque *tmpstr;
  size_t s_len;
  int result;

  s_len = 0;
  if (lz)
    result = _gnutls_mpi_print_lz (mpi, NULL, &s_len);
  else
    result = _gnutls_mpi_print (mpi, NULL, &s_len);

  if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
    {
      gnutls_assert ();
      return result;
    }

  tmpstr = gnutls_malloc (s_len);
  if (tmpstr == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  if (lz)
    result = _gnutls_mpi_print_lz (mpi, tmpstr, &s_len);
  else
    result = _gnutls_mpi_print (mpi, tmpstr, &s_len);

  if (result != 0)
    {
      gnutls_assert ();
      gnutls_free (tmpstr);
      return GNUTLS_E_MPI_PRINT_FAILED;
    }

  result = asn1_write_value (node, value, tmpstr, s_len);

  gnutls_free (tmpstr);

  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  return 0;
}
Exemple #3
0
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
 */
static int
_encode_rsa (ASN1_TYPE * c2, mpi_t * params)
{
  int result, i;
  size_t size[8], total;
  opaque *m_data, *pube_data, *prie_data;
  opaque *p1_data, *p2_data, *u_data, *exp1_data, *exp2_data;
  opaque *all_data = NULL, *p;
  mpi_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u = NULL;
  opaque null = '\0';

  /* Read all the sizes */
  total = 0;
  for (i = 0; i < 5; i++)
    {
      _gnutls_mpi_print_lz (NULL, &size[i], params[i]);
      total += size[i];
    }

  /* Now generate exp1 and exp2
   */
  exp1 = _gnutls_mpi_salloc_like (params[0]);	/* like modulus */
  if (exp1 == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  exp2 = _gnutls_mpi_salloc_like (params[0]);
  if (exp2 == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  q1 = _gnutls_mpi_salloc_like (params[4]);
  if (q1 == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  p1 = _gnutls_mpi_salloc_like (params[3]);
  if (p1 == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  u = _gnutls_mpi_salloc_like (params[3]);
  if (u == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  _gnutls_mpi_invm (u, params[4], params[3]);
  /* inverse of q mod p */
  _gnutls_mpi_print_lz (NULL, &size[5], u);
  total += size[5];

  _gnutls_mpi_sub_ui (p1, params[3], 1);
  _gnutls_mpi_sub_ui (q1, params[4], 1);

  _gnutls_mpi_mod (exp1, params[2], p1);
  _gnutls_mpi_mod (exp2, params[2], q1);


  /* calculate exp's size */
  _gnutls_mpi_print_lz (NULL, &size[6], exp1);
  total += size[6];

  _gnutls_mpi_print_lz (NULL, &size[7], exp2);
  total += size[7];

  /* Encoding phase.
   * allocate data enough to hold everything
   */
  all_data = gnutls_secure_malloc (total);
  if (all_data == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  p = all_data;
  m_data = p;
  p += size[0];
  pube_data = p;
  p += size[1];
  prie_data = p;
  p += size[2];
  p1_data = p;
  p += size[3];
  p2_data = p;
  p += size[4];
  u_data = p;
  p += size[5];
  exp1_data = p;
  p += size[6];
  exp2_data = p;

  _gnutls_mpi_print_lz (m_data, &size[0], params[0]);
  _gnutls_mpi_print_lz (pube_data, &size[1], params[1]);
  _gnutls_mpi_print_lz (prie_data, &size[2], params[2]);
  _gnutls_mpi_print_lz (p1_data, &size[3], params[3]);
  _gnutls_mpi_print_lz (p2_data, &size[4], params[4]);
  _gnutls_mpi_print_lz (u_data, &size[5], u);
  _gnutls_mpi_print_lz (exp1_data, &size[6], exp1);
  _gnutls_mpi_print_lz (exp2_data, &size[7], exp2);

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

  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, size[0])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "publicExponent",
				  pube_data, size[1])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "privateExponent",
				  prie_data, size[2])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "prime1",
				  p1_data, size[3])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "prime2",
				  p2_data, size[4])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "exponent1",
				  exp1_data, size[6])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "exponent2",
				  exp2_data, size[7])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "coefficient",
				  u_data, size[5])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  _gnutls_mpi_release (&exp1);
  _gnutls_mpi_release (&exp2);
  _gnutls_mpi_release (&q1);
  _gnutls_mpi_release (&p1);
  _gnutls_mpi_release (&u);
  gnutls_free (all_data);

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

  return 0;

cleanup:
  _gnutls_mpi_release (&u);
  _gnutls_mpi_release (&exp1);
  _gnutls_mpi_release (&exp2);
  _gnutls_mpi_release (&q1);
  _gnutls_mpi_release (&p1);
  asn1_delete_structure (c2);
  gnutls_free (all_data);

  return result;
}
Exemple #4
0
/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
 */
static int
_encode_dsa (ASN1_TYPE * c2, mpi_t * params)
{
  int result, i;
  size_t size[DSA_PRIVATE_PARAMS], total;
  opaque *p_data, *q_data, *g_data, *x_data, *y_data;
  opaque *all_data = NULL, *p;
  opaque null = '\0';

  /* Read all the sizes */
  total = 0;
  for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
    {
      _gnutls_mpi_print_lz (NULL, &size[i], params[i]);
      total += size[i];
    }

  /* Encoding phase.
   * allocate data enough to hold everything
   */
  all_data = gnutls_secure_malloc (total);
  if (all_data == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  p = all_data;
  p_data = p;
  p += size[0];
  q_data = p;
  p += size[1];
  g_data = p;
  p += size[2];
  y_data = p;
  p += size[3];
  x_data = p;

  _gnutls_mpi_print_lz (p_data, &size[0], params[0]);
  _gnutls_mpi_print_lz (q_data, &size[1], params[1]);
  _gnutls_mpi_print_lz (g_data, &size[2], params[2]);
  _gnutls_mpi_print_lz (y_data, &size[3], params[3]);
  _gnutls_mpi_print_lz (x_data, &size[4], params[4]);

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

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

  /* Write PRIME 
   */
  if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "priv",
				  x_data, size[4])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  gnutls_free (all_data);

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

  return 0;

cleanup:
  asn1_delete_structure (c2);
  gnutls_free (all_data);

  return result;
}
Exemple #5
0
/**
 * gnutls_dh_params_export_pkcs3 - export DH params to a pkcs3 structure
 * @params: Holds the DH parameters
 * @format: the format of output params. One of PEM or DER.
 * @params_data: will contain a PKCS3 DHParams structure PEM or DER encoded
 * @params_data_size: holds the size of params_data (and will be replaced by the actual size of parameters)
 *
 * This function will export the given dh parameters to a PKCS3
 * DHParams structure. This is the format generated by "openssl dhparam" tool.
 * If the buffer provided is not long enough to hold the output, then
 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
 *
 * If the structure is PEM encoded, it will have a header
 * of "BEGIN DH PARAMETERS".
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
 *   otherwise an error code is returned.
 **/
int
gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
                               gnutls_x509_crt_fmt_t format,
                               unsigned char *params_data,
                               size_t * params_data_size)
{
    ASN1_TYPE c2;
    int result, _params_data_size;
    size_t g_size, p_size;
    opaque *p_data, *g_data;
    opaque *all_data;

    _gnutls_mpi_print_lz (params->params[1], NULL, &g_size);
    _gnutls_mpi_print_lz (params->params[0], NULL, &p_size);

    all_data = gnutls_malloc (g_size + p_size);
    if (all_data == NULL)
    {
        gnutls_assert ();
        return GNUTLS_E_MEMORY_ERROR;
    }

    p_data = &all_data[0];
    g_data = &all_data[p_size];

    _gnutls_mpi_print_lz (params->params[0], p_data, &p_size);
    _gnutls_mpi_print_lz (params->params[1], g_data, &g_size);

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

    if ((result = asn1_create_element
                  (_gnutls_get_gnutls_asn (), "GNUTLS.DHParameter", &c2))
            != ASN1_SUCCESS)
    {
        gnutls_assert ();
        gnutls_free (all_data);
        return _gnutls_asn2err (result);
    }

    /* Write PRIME
     */
    if ((result = asn1_write_value (c2, "prime",
                                    p_data, p_size)) != ASN1_SUCCESS)
    {
        gnutls_assert ();
        gnutls_free (all_data);
        asn1_delete_structure (&c2);
        return _gnutls_asn2err (result);
    }

    /* Write the GENERATOR
     */
    if ((result = asn1_write_value (c2, "base",
                                    g_data, g_size)) != ASN1_SUCCESS)
    {
        gnutls_assert ();
        gnutls_free (all_data);
        asn1_delete_structure (&c2);
        return _gnutls_asn2err (result);
    }

    gnutls_free (all_data);

    if ((result = asn1_write_value (c2, "privateValueLength",
                                    NULL, 0)) != ASN1_SUCCESS)
    {
        gnutls_assert ();
        asn1_delete_structure (&c2);
        return _gnutls_asn2err (result);
    }

    if (format == GNUTLS_X509_FMT_DER)
    {
        if (params_data == NULL)
            *params_data_size = 0;

        _params_data_size = *params_data_size;
        result =
            asn1_der_coding (c2, "", params_data, &_params_data_size, NULL);
        *params_data_size = _params_data_size;
        asn1_delete_structure (&c2);

        if (result != ASN1_SUCCESS)
        {
            gnutls_assert ();
            if (result == ASN1_MEM_ERROR)
                return GNUTLS_E_SHORT_MEMORY_BUFFER;

            return _gnutls_asn2err (result);
        }

    }
    else
    {   /* PEM */
        opaque *tmp;
        opaque *out;
        int len;

        len = 0;
        asn1_der_coding (c2, "", NULL, &len, NULL);

        tmp = gnutls_malloc (len);
        if (tmp == NULL)
        {
            gnutls_assert ();
            asn1_delete_structure (&c2);
            return GNUTLS_E_MEMORY_ERROR;
        }

        if ((result =
                    asn1_der_coding (c2, "", tmp, &len, NULL)) != ASN1_SUCCESS)
        {
            gnutls_assert ();
            gnutls_free (tmp);
            asn1_delete_structure (&c2);
            return _gnutls_asn2err (result);
        }

        asn1_delete_structure (&c2);

        result = _gnutls_fbase64_encode ("DH PARAMETERS", tmp, len, &out);

        gnutls_free (tmp);

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

        if (result == 0)
        {   /* oooops */
            gnutls_assert ();
            gnutls_free (out);
            return GNUTLS_E_INTERNAL_ERROR;
        }

        if ((unsigned) result > *params_data_size)
        {
            gnutls_assert ();
            gnutls_free (out);
            *params_data_size = result;
            return GNUTLS_E_SHORT_MEMORY_BUFFER;
        }

        *params_data_size = result - 1;

        if (params_data)
            memcpy (params_data, out, result);

        gnutls_free (out);

    }

    return 0;
}
Exemple #6
0
/**
 * gnutls_dh_params_export2_pkcs3:
 * @params: Holds the DH parameters
 * @format: the format of output params. One of PEM or DER.
 * @out: will contain a PKCS3 DHParams structure PEM or DER encoded
 *
 * This function will export the given dh parameters to a PKCS3
 * DHParams structure. This is the format generated by "openssl dhparam" tool.
 * The data in @out will be allocated using gnutls_malloc().
 *
 * If the structure is PEM encoded, it will have a header
 * of "BEGIN DH PARAMETERS".
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 *
 * Since: 3.1.3
 **/
int
gnutls_dh_params_export2_pkcs3(gnutls_dh_params_t params,
			       gnutls_x509_crt_fmt_t format,
			       gnutls_datum_t * out)
{
	ASN1_TYPE c2;
	int result;
	size_t g_size, p_size;
	uint8_t *p_data, *g_data;
	uint8_t *all_data;

	_gnutls_mpi_print_lz(params->params[1], NULL, &g_size);
	_gnutls_mpi_print_lz(params->params[0], NULL, &p_size);

	all_data = gnutls_malloc(g_size + p_size);
	if (all_data == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	p_data = &all_data[0];
	_gnutls_mpi_print_lz(params->params[0], p_data, &p_size);

	g_data = &all_data[p_size];
	_gnutls_mpi_print_lz(params->params[1], g_data, &g_size);


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

	if ((result = asn1_create_element
	     (_gnutls_get_gnutls_asn(), "GNUTLS.DHParameter", &c2))
	    != ASN1_SUCCESS) {
		gnutls_assert();
		gnutls_free(all_data);
		return _gnutls_asn2err(result);
	}

	/* Write PRIME 
	 */
	if ((result = asn1_write_value(c2, "prime",
				       p_data, p_size)) != ASN1_SUCCESS) {
		gnutls_assert();
		gnutls_free(all_data);
		asn1_delete_structure(&c2);
		return _gnutls_asn2err(result);
	}

	if (params->q_bits > 0)
		result =
		    _gnutls_x509_write_uint32(c2, "privateValueLength",
					      params->q_bits);
	else
		result =
		    asn1_write_value(c2, "privateValueLength", NULL, 0);

	if (result < 0) {
		gnutls_assert();
		gnutls_free(all_data);
		asn1_delete_structure(&c2);
		return _gnutls_asn2err(result);
	}

	/* Write the GENERATOR
	 */
	if ((result = asn1_write_value(c2, "base",
				       g_data, g_size)) != ASN1_SUCCESS) {
		gnutls_assert();
		gnutls_free(all_data);
		asn1_delete_structure(&c2);
		return _gnutls_asn2err(result);
	}

	gnutls_free(all_data);


	if (format == GNUTLS_X509_FMT_DER) {
		result = _gnutls_x509_der_encode(c2, "", out, 0);

		asn1_delete_structure(&c2);

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

	} else {		/* PEM */
		gnutls_datum_t t;

		result = _gnutls_x509_der_encode(c2, "", &t, 0);

		asn1_delete_structure(&c2);

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

		result =
		    _gnutls_fbase64_encode("DH PARAMETERS", t.data, t.size,
					   out);

		gnutls_free(t.data);

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

	return 0;
}