예제 #1
0
/* Reads and returns the PK algorithm of the given certificate-like
 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
 */
int
_gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
                               unsigned int *bits)
{
  int result;
  int algo;
  char oid[64];
  int len;
  gnutls_pk_params_st params;
  char name[128];

  gnutls_pk_params_init(&params);

  _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
  len = sizeof (oid);
  result = asn1_read_value (src, name, oid, &len);

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

  algo = _gnutls_x509_oid2pk_algorithm (oid);
  if (algo == GNUTLS_PK_UNKNOWN)
    {
      _gnutls_debug_log
        ("%s: unknown public key algorithm: %s\n", __func__, oid);
    }

  if (bits == NULL)
    {
      return algo;
    }

  /* Now read the parameters' bits 
   */
  result = _gnutls_get_asn_mpis(src, src_name, &params);
  if (result < 0)
    return gnutls_assert_val(result);

  bits[0] = pubkey_to_bits(algo, &params);

  gnutls_pk_params_release(&params);
  return algo;
}
예제 #2
0
/* Encodes and copies the private key parameters into a
 * subjectPublicKeyInfo structure.
 *
 */
int
_gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
                                         const char *dst_name,
                                         gnutls_pk_algorithm_t
                                         pk_algorithm, gnutls_pk_params_st * params)
{
  const char *pk;
  gnutls_datum_t der = { NULL, 0 };
  int result;
  char name[128];

  pk = _gnutls_x509_pk_to_oid (pk_algorithm);
  if (pk == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  /* write the OID
   */
  _asnstr_append_name (name, sizeof (name), dst_name, ".algorithm.algorithm");

  result = asn1_write_value (dst, name, pk, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  result = _gnutls_x509_write_pubkey_params (pk_algorithm, params, &der);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  _asnstr_append_name (name, sizeof (name), dst_name,
                       ".algorithm.parameters");

  result = asn1_write_value (dst, name, der.data, der.size);

  _gnutls_free_datum (&der);

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

  result = _gnutls_x509_write_pubkey (pk_algorithm, params, &der);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  /* Write the DER parameters. (in bits)
   */
  _asnstr_append_name (name, sizeof (name), dst_name,
                       ".subjectPublicKey");
  result = asn1_write_value (dst, name, der.data, der.size * 8);
  _gnutls_free_datum (&der);

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

  return 0;
}
예제 #3
0
/* Reads and returns the PK algorithm of the given certificate-like
 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
 */
int
_gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
                               unsigned int *bits)
{
    int result;
    opaque *str = NULL;
    int algo;
    char oid[64];
    int len;
    bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
    char name[128];


    _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
    len = sizeof (oid);
    result = asn1_read_value (src, name, oid, &len);

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

    algo = _gnutls_x509_oid2pk_algorithm (oid);
    if (algo == GNUTLS_PK_UNKNOWN)
    {
        _gnutls_x509_log
        ("%s: unknown public key algorithm: %s\n", __func__, oid);
    }

    if (bits == NULL)
    {
        return algo;
    }

    /* Now read the parameters' bits
     */
    _asnstr_append_name (name, sizeof (name), src_name, ".subjectPublicKey");

    len = 0;
    result = asn1_read_value (src, name, NULL, &len);
    if (result != ASN1_MEM_ERROR)
    {
        gnutls_assert ();
        return _gnutls_asn2err (result);
    }

    if (len % 8 != 0)
    {
        gnutls_assert ();
        return GNUTLS_E_CERTIFICATE_ERROR;
    }

    len /= 8;

    str = gnutls_malloc (len);
    if (str == NULL)
    {
        gnutls_assert ();
        return GNUTLS_E_MEMORY_ERROR;
    }

    _asnstr_append_name (name, sizeof (name), src_name, ".subjectPublicKey");

    result = asn1_read_value (src, name, str, &len);

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

    len /= 8;

    switch (algo)
    {
    case GNUTLS_PK_RSA:
    {
        if ((result = _gnutls_x509_read_rsa_params (str, len, params)) < 0)
        {
            gnutls_assert ();
            return result;
        }

        bits[0] = _gnutls_mpi_get_nbits (params[0]);

        _gnutls_mpi_release (&params[0]);
        _gnutls_mpi_release (&params[1]);
    }
    break;
    case GNUTLS_PK_DSA:
    {

        if ((result = _gnutls_x509_read_dsa_pubkey (str, len, params)) < 0)
        {
            gnutls_assert ();
            return result;
        }

        bits[0] = _gnutls_mpi_get_nbits (params[3]);

        _gnutls_mpi_release (&params[3]);
    }
    break;
    }

    gnutls_free (str);
    return algo;
}
예제 #4
0
/* Extracts DSA and RSA parameters from a certificate.
 */
int
_gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
                      bigint_t * params, int *params_size)
{
  int result;
  char name[256];
  gnutls_datum_t tmp = { NULL, 0 };
  gnutls_pk_algorithm_t pk_algorithm;

  result = _gnutls_x509_get_pk_algorithm (asn, root, NULL);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  pk_algorithm = result;

  /* Read the algorithm's parameters
   */
  _asnstr_append_name (name, sizeof (name), root, ".subjectPublicKey");
  result = _gnutls_x509_read_value (asn, name, &tmp, 2);

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

  switch (pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      /* params[0] is the modulus,
       * params[1] is the exponent
       */
      if (*params_size < RSA_PUBLIC_PARAMS)
        {
          gnutls_assert ();
          /* internal error. Increase the bigint_ts in params */
          result = GNUTLS_E_INTERNAL_ERROR;
          goto error;
        }

      if ((result =
           _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
        {
          gnutls_assert ();
          goto error;
        }
      *params_size = RSA_PUBLIC_PARAMS;

      break;
    case GNUTLS_PK_DSA:
      /* params[0] is p,
       * params[1] is q,
       * params[2] is q,
       * params[3] is pub.
       */

      if (*params_size < DSA_PUBLIC_PARAMS)
        {
          gnutls_assert ();
          /* internal error. Increase the bigint_ts in params */
          result = GNUTLS_E_INTERNAL_ERROR;
          goto error;
        }

      if ((result =
           _gnutls_x509_read_dsa_pubkey (tmp.data, tmp.size, params)) < 0)
        {
          gnutls_assert ();
          goto error;
        }

      /* Now read the parameters
       */
      _gnutls_free_datum (&tmp);

      _asnstr_append_name (name, sizeof (name), root,
                           ".algorithm.parameters");
      result = _gnutls_x509_read_value (asn, name, &tmp, 0);

      /* FIXME: If the parameters are not included in the certificate
       * then the issuer's parameters should be used. This is not
       * done yet.
       */

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

      if ((result =
           _gnutls_x509_read_dsa_params (tmp.data, tmp.size, params)) < 0)
        {
          gnutls_assert ();
          goto error;
        }
      *params_size = DSA_PUBLIC_PARAMS;

      break;

    default:
      /* other types like DH
       * currently not supported
       */
      gnutls_assert ();
      result = GNUTLS_E_X509_CERTIFICATE_ERROR;
      goto error;
    }

  result = 0;

error:
  _gnutls_free_datum (&tmp);
  return result;
}
예제 #5
0
/* Encodes and copies the private key parameters into a
 * subjectPublicKeyInfo structure.
 *
 */
int
_gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
        const char *dst_name,
        gnutls_pk_algorithm_t
        pk_algorithm, bigint_t * params,
        int params_size)
{
    const char *pk;
    gnutls_datum_t der = { NULL, 0 };
    int result;
    char name[128];

    pk = _gnutls_x509_pk_to_oid (pk_algorithm);
    if (pk == NULL)
    {
        gnutls_assert ();
        return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

    /* write the OID
     */
    _asnstr_append_name (name, sizeof (name), dst_name, ".algorithm.algorithm");

    result = asn1_write_value (dst, name, pk, 1);
    if (result != ASN1_SUCCESS)
    {
        gnutls_assert ();
        return _gnutls_asn2err (result);
    }

    if (pk_algorithm == GNUTLS_PK_RSA)
    {
        /* disable parameters, which are not used in RSA.
         */
        _asnstr_append_name (name, sizeof (name), dst_name,
                             ".algorithm.parameters");

        result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE);
        if (result != ASN1_SUCCESS)
        {
            gnutls_assert ();
            return _gnutls_asn2err (result);
        }

        result = _gnutls_x509_write_rsa_params (params, params_size, &der);
        if (result < 0)
        {
            gnutls_assert ();
            return result;
        }

        /* Write the DER parameters. (in bits)
         */
        _asnstr_append_name (name, sizeof (name), dst_name,
                             ".subjectPublicKey");
        result = asn1_write_value (dst, name, der.data, der.size * 8);

        _gnutls_free_datum (&der);

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

        result = _gnutls_x509_write_dsa_params (params, params_size, &der);
        if (result < 0)
        {
            gnutls_assert ();
            return result;
        }

        /* Write the DER parameters.
         */
        _asnstr_append_name (name, sizeof (name), dst_name,
                             ".algorithm.parameters");
        result = asn1_write_value (dst, name, der.data, der.size);

        _gnutls_free_datum (&der);

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

        result = _gnutls_x509_write_dsa_public_key (params, params_size, &der);
        if (result < 0)
        {
            gnutls_assert ();
            return result;
        }

        _asnstr_append_name (name, sizeof (name), dst_name,
                             ".subjectPublicKey");
        result = asn1_write_value (dst, name, der.data, der.size * 8);

        _gnutls_free_datum (&der);

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

    }
    else
        return GNUTLS_E_UNIMPLEMENTED_FEATURE;

    return 0;
}