/* Converts an RSA PKCS#1 key to
 * an internal structure (gnutls_private_key)
 */
ASN1_TYPE
_gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
                                      gnutls_x509_privkey_t pkey)
{
  int result;
  ASN1_TYPE pkey_asn;

  gnutls_pk_params_init(&pkey->params);

  if ((result =
       asn1_create_element (_gnutls_get_gnutls_asn (),
                            "GNUTLS.RSAPrivateKey",
                            &pkey_asn)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return NULL;
    }

  result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      goto error;
    }

  if ((result = _gnutls_x509_read_int (pkey_asn, "modulus",
                                       &pkey->params.params[0])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result =
       _gnutls_x509_read_int (pkey_asn, "publicExponent",
                              &pkey->params.params[1])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result =
       _gnutls_x509_read_int (pkey_asn, "privateExponent",
                              &pkey->params.params[2])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "prime1",
                                       &pkey->params.params[3])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "prime2",
                                       &pkey->params.params[4])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient",
                                       &pkey->params.params[5])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1",
                                       &pkey->params.params[6])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2",
                                       &pkey->params.params[7])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params);
  if (result < 0)
    {
      gnutls_assert ();
      goto error;
    }

  pkey->params.params_nr = RSA_PRIVATE_PARAMS;

  return pkey_asn;

error:
  asn1_delete_structure (&pkey_asn);
  gnutls_pk_params_release (&pkey->params);
  return NULL;

}
/**
 * gnutls_x509_privkey_import_rsa_raw2:
 * @key: The structure to store the parsed key
 * @m: holds the modulus
 * @e: holds the public exponent
 * @d: holds the private exponent
 * @p: holds the first prime (p)
 * @q: holds the second prime (q)
 * @u: holds the coefficient
 * @e1: holds e1 = d mod (p-1)
 * @e2: holds e2 = d mod (q-1)
 *
 * This function will convert the given RSA raw parameters to the
 * native #gnutls_x509_privkey_t format.  The output will be stored in
 * @key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
                                     const gnutls_datum_t * m,
                                     const gnutls_datum_t * e,
                                     const gnutls_datum_t * d,
                                     const gnutls_datum_t * p,
                                     const gnutls_datum_t * q,
                                     const gnutls_datum_t * u,
                                     const gnutls_datum_t * e1,
                                     const gnutls_datum_t * e2)
{
  int ret;
  size_t siz = 0;

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

  gnutls_pk_params_init(&key->params);

  siz = m->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = e->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = d->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = p->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = q->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = u->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  if (e1 && e2)
    {
      siz = e1->size;
      if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz))
        {
          gnutls_assert ();
          ret = GNUTLS_E_MPI_SCAN_FAILED;
          goto cleanup;
        }
      key->params.params_nr++;

      siz = e2->size;
      if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz))
        {
          gnutls_assert ();
          ret = GNUTLS_E_MPI_SCAN_FAILED;
          goto cleanup;
        }
      key->params.params_nr++;
    }

  ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  key->params.params_nr = RSA_PRIVATE_PARAMS;
  key->pk_algorithm = GNUTLS_PK_RSA;

  return 0;

cleanup:
  gnutls_pk_params_release(&key->params);
  return ret;

}
Esempio n. 3
0
File: privkey.c Progetto: sqs/gnutls
/**
 * gnutls_x509_privkey_import_rsa_raw2:
 * @key: The structure to store the parsed key
 * @m: holds the modulus
 * @e: holds the public exponent
 * @d: holds the private exponent
 * @p: holds the first prime (p)
 * @q: holds the second prime (q)
 * @u: holds the coefficient
 *
 * This function will convert the given RSA raw parameters to the
 * native #gnutls_x509_privkey_t format.  The output will be stored in
 * @key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
                                     const gnutls_datum_t * m,
                                     const gnutls_datum_t * e,
                                     const gnutls_datum_t * d,
                                     const gnutls_datum_t * p,
                                     const gnutls_datum_t * q,
                                     const gnutls_datum_t * u,
                                     const gnutls_datum_t * e1,
                                     const gnutls_datum_t * e2)
{
  int i = 0, ret;
  size_t siz = 0;
  gnutls_pk_params_st pk_params;

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

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

  key->params_size = 0;

  siz = m->size;
  if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz))
    {
      gnutls_assert ();
      FREE_RSA_PRIVATE_PARAMS;
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  key->params_size++;

  siz = e->size;
  if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz))
    {
      gnutls_assert ();
      FREE_RSA_PRIVATE_PARAMS;
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  key->params_size++;

  siz = d->size;
  if (_gnutls_mpi_scan_nz (&key->params[2], d->data, siz))
    {
      gnutls_assert ();
      FREE_RSA_PRIVATE_PARAMS;
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  key->params_size++;

  siz = p->size;
  if (_gnutls_mpi_scan_nz (&key->params[3], p->data, siz))
    {
      gnutls_assert ();
      FREE_RSA_PRIVATE_PARAMS;
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  key->params_size++;

  siz = q->size;
  if (_gnutls_mpi_scan_nz (&key->params[4], q->data, siz))
    {
      gnutls_assert ();
      FREE_RSA_PRIVATE_PARAMS;
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  key->params_size++;

  siz = u->size;
  if (_gnutls_mpi_scan_nz (&key->params[5], u->data, siz))
    {
      gnutls_assert ();
      FREE_RSA_PRIVATE_PARAMS;
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  key->params_size++;

  if (e1 && e2)
    {
      siz = e1->size;
      if (_gnutls_mpi_scan_nz (&key->params[6], e1->data, siz))
        {
          gnutls_assert ();
          FREE_RSA_PRIVATE_PARAMS;
          return GNUTLS_E_MPI_SCAN_FAILED;
        }
      key->params_size++;

      siz = e2->size;
      if (_gnutls_mpi_scan_nz (&key->params[7], e2->data, siz))
        {
          gnutls_assert ();
          FREE_RSA_PRIVATE_PARAMS;
          return GNUTLS_E_MPI_SCAN_FAILED;
        }
      key->params_size++;
    }

  for (i = 0; i < key->params_size; i++)
    {
      pk_params.params[i] = key->params[i];
    }

  pk_params.params_nr = key->params_size;

  ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params);
  if (ret < 0)
    {
      gnutls_assert ();
      FREE_RSA_PRIVATE_PARAMS;
      return ret;
    }

  for (i = 0; i < pk_params.params_nr; i++)
    {
      key->params[i] = pk_params.params[i];
    }
  key->params_size = pk_params.params_nr;

  if (!key->crippled)
    {
      ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
      if (ret < 0)
        {
          gnutls_assert ();
          FREE_RSA_PRIVATE_PARAMS;
          return ret;
        }
    }

  key->params_size = RSA_PRIVATE_PARAMS;
  key->pk_algorithm = GNUTLS_PK_RSA;

  return 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;
}
Esempio n. 5
0
File: privkey.c Progetto: 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;
}
Esempio n. 6
0
/* Extracts DSA and RSA parameters from a certificate.
 */
int
_gnutls_openpgp_privkey_get_mpis(gnutls_openpgp_privkey_t pkey,
				 uint32_t * keyid /*[2] */ ,
				 gnutls_pk_params_st * params)
{
	int result;
	unsigned int i, pk_algorithm;
	cdk_packet_t pkt;
	unsigned total;

	gnutls_pk_params_init(params);

	if (keyid == NULL)
		pkt =
		    cdk_kbnode_find_packet(pkey->knode,
					   CDK_PKT_SECRET_KEY);
	else
		pkt = _gnutls_openpgp_find_key(pkey->knode, keyid, 1);

	if (pkt == NULL) {
		gnutls_assert();
		return GNUTLS_E_OPENPGP_GETKEY_FAILED;
	}

	pk_algorithm =
	    _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo);

	switch (pk_algorithm) {
	case GNUTLS_PK_RSA:
		/* openpgp does not hold all parameters as in PKCS #1
		 */
		total = RSA_PRIVATE_PARAMS - 2;
		break;
	case GNUTLS_PK_DSA:
		total = DSA_PRIVATE_PARAMS;
		break;
	default:
		gnutls_assert();
		return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
	}

	for (i = 0; i < total; i++) {
		result =
		    _gnutls_read_pgp_mpi(pkt, 1, i, &params->params[i]);
		if (result < 0) {
			gnutls_assert();
			goto error;
		}
		params->params_nr++;
	}

	/* fixup will generate exp1 and exp2 that are not
	 * available here.
	 */
	result = _gnutls_pk_fixup(pk_algorithm, GNUTLS_IMPORT, params);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	return 0;

      error:
	gnutls_pk_params_clear(params);
	gnutls_pk_params_release(params);

	return result;
}
Esempio n. 7
0
/**
 * gnutls_x509_privkey_import_pkcs8:
 * @key: The data to store the parsed key
 * @data: The DER or PEM encoded key.
 * @format: One of DER or PEM
 * @password: the password to decrypt the key (if it is encrypted).
 * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
 *
 * This function will convert the given DER or PEM encoded PKCS8 2.0
 * encrypted key to the native gnutls_x509_privkey_t format. The
 * output will be stored in @key.  Both RSA and DSA keys can be
 * imported, and flags can only be used to indicate an unencrypted
 * key.
 *
 * The @password can be either ASCII or UTF-8 in the default PBES2
 * encryption schemas, or ASCII for the PKCS12 schemas.
 *
 * If the Certificate is PEM encoded it should have a header of
 * "ENCRYPTED PRIVATE KEY", or "PRIVATE KEY". You only need to
 * specify the flags if the key is DER encoded, since in that case
 * the encryption status cannot be auto-detected.
 *
 * If the %GNUTLS_PKCS_PLAIN flag is specified and the supplied data
 * are encrypted then %GNUTLS_E_DECRYPTION_FAILED is returned.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
				 const gnutls_datum_t * data,
				 gnutls_x509_crt_fmt_t format,
				 const char *password, unsigned int flags)
{
	int result = 0, need_free = 0;
	gnutls_datum_t _data;

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

	_data.data = data->data;
	_data.size = data->size;

	key->params.algo = GNUTLS_PK_UNKNOWN;

	/* If the Certificate is in PEM format then decode it
	 */
	if (format == GNUTLS_X509_FMT_PEM) {
		/* Try the first header 
		 */
		result =
		    _gnutls_fbase64_decode(PEM_UNENCRYPTED_PKCS8,
					   data->data, data->size, &_data);

		if (result < 0) {	/* Try the encrypted header 
					 */
			result =
			    _gnutls_fbase64_decode(PEM_PKCS8, data->data,
						   data->size, &_data);

			if (result < 0) {
				gnutls_assert();
				return result;
			}
		} else if (flags == 0)
			flags |= GNUTLS_PKCS_PLAIN;

		need_free = 1;
	}

	if (key->expanded) {
		_gnutls_x509_privkey_reinit(key);
	}
	key->expanded = 1;

	/* Here we don't check for password == NULL to maintain a backwards
	 * compatibility behavior, with old versions that were encrypting using
	 * a NULL password.
	 */
	if (flags & GNUTLS_PKCS_PLAIN) {
		result = decode_private_key_info(&_data, key);
		if (result < 0) {	/* check if it is encrypted */
			if (pkcs8_key_decode(&_data, "", key, 0) == 0)
				result = GNUTLS_E_DECRYPTION_FAILED;
		}
	} else {		/* encrypted. */
		result = pkcs8_key_decode(&_data, password, key, 1);
	}

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

	/* This part is necessary to get the public key on certain algorithms.
	 * In the import above we only get the private key. */
	result =
	    _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}

	if (need_free)
		_gnutls_free_datum(&_data);

	/* The key has now been decoded.
	 */
	return 0;

 cleanup:
	asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
	key->params.algo = GNUTLS_PK_UNKNOWN;
	if (need_free)
		_gnutls_free_datum(&_data);
	return result;
}
Esempio n. 8
0
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
 */
static int
_gnutls_asn1_encode_rsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
{
    int result, ret;
    uint8_t null = '\0';
    gnutls_pk_params_st pk_params;

    /* we do copy the parameters into a new structure to run _gnutls_pk_fixup,
     * i.e., regenerate some parameters in case they were broken */
    gnutls_pk_params_init(&pk_params);

    ret = _gnutls_pk_params_copy(&pk_params, 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 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();
        ret = _gnutls_asn2err(result);
        goto cleanup;
    }

    /* Write PRIME
     */
    ret =
        _gnutls_x509_write_int(*c2, "modulus",
                               params->params[RSA_MODULUS], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_int(*c2, "publicExponent",
                               params->params[RSA_PUB], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "privateExponent",
                                   params->params[RSA_PRIV], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "prime1",
                                   params->params[RSA_PRIME1], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "prime2",
                                   params->params[RSA_PRIME2], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "coefficient",
                                   params->params[RSA_COEF], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "exponent1",
                                   params->params[RSA_E1], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "exponent2",
                                   params->params[RSA_E2], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

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

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

    ret = 0;

cleanup:
    if (ret < 0)
        asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);

    gnutls_pk_params_clear(&pk_params);
    gnutls_pk_params_release(&pk_params);
    return ret;
}
Esempio n. 9
0
/* Extracts DSA and RSA parameters from a certificate.
 */
int
_gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey,
                                  uint32_t * keyid /*[2] */ ,
                                  bigint_t * params, int *params_size)
{
  int result, i;
  int pk_algorithm;
  gnutls_pk_params_st pk_params;
  cdk_packet_t pkt;

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

  if (keyid == NULL)
    pkt = cdk_kbnode_find_packet (pkey->knode, CDK_PKT_SECRET_KEY);
  else
    pkt = _gnutls_openpgp_find_key (pkey->knode, keyid, 1);

  if (pkt == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_OPENPGP_GETKEY_FAILED;
    }

  pk_algorithm =
    _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);

  switch (pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      /* openpgp does not hold all parameters as in PKCS #1
       */
      pk_params.params_nr = RSA_PRIVATE_PARAMS - 2;
      break;
    case GNUTLS_PK_DSA:
      pk_params.params_nr = DSA_PRIVATE_PARAMS;
      break;
    default:
      gnutls_assert ();
      return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
    }

  for (i = 0; i < pk_params.params_nr; i++)
    {
      result = _gnutls_read_pgp_mpi (pkt, 1, i, &pk_params.params[i]);
      if (result < 0)
        {
          gnutls_assert ();
          goto error;
        }
    }
  
  /* fixup will generate exp1 and exp2 that are not
   * available here.
   */
  result = _gnutls_pk_fixup (pk_algorithm, GNUTLS_IMPORT, &pk_params);
  if (result < 0)
    {
      gnutls_assert ();
      goto error;
    }

  if (*params_size < pk_params.params_nr)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  *params_size = pk_params.params_nr;
  for (i = 0; i < pk_params.params_nr; i++)
    params[i] = pk_params.params[i];

  return 0;

error:
  {
    int j;
    for (j = 0; j < i; j++)
      _gnutls_mpi_release (&pk_params.params[j]);
  }

  return result;
}