Esempio n. 1
0
/* Reads a value from an ASN1 tree, and puts the output
 * in an allocated variable in the given datum.
 * If str is non zero, then the output will be treated as
 * an octet string.
 */
int
_gnutls_x509_read_value (ASN1_TYPE c, const char *root,
			 gnutls_datum_t * ret, int str)
{
  int len = 0, result;
  size_t slen;
  opaque *tmp = NULL;

  result = asn1_read_value (c, root, NULL, &len);
  if (result != ASN1_MEM_ERROR)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      return result;
    }

  tmp = gnutls_malloc (len);
  if (tmp == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  result = asn1_read_value (c, root, tmp, &len);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Extract the OCTET STRING.
   */

  if (str)
    {
      slen = len;
      result = _gnutls_x509_decode_octet_string (NULL, tmp, slen, tmp, &slen);
      if (result < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
      len = slen;
    }

  ret->data = tmp;
  ret->size = len;

  return 0;

cleanup:
  gnutls_free (tmp);
  return result;

}
Esempio n. 2
0
/* Decodes the SafeContents, and puts the output in
 * the given bag. 
 */
int
_pkcs12_decode_safe_contents (const gnutls_datum_t * content,
			      gnutls_pkcs12_bag_t bag)
{
  char oid[MAX_OID_SIZE], root[ASN1_MAX_NAME_SIZE];
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  int len, result;
  int bag_type;
  gnutls_datum_t attr_val;
  int count = 0, i, attributes, j;
  size_t size;

  /* Step 1. Extract the SEQUENCE.
   */

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
	&c2)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  result = asn1_der_decoding (&c2, content->data, content->size, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Count the number of bags
   */
  result = asn1_number_of_elements (c2, "", &count);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  bag->bag_elements = MIN (MAX_BAG_ELEMENTS, count);

  for (i = 0; i < bag->bag_elements; i++)
    {

      snprintf (root, sizeof (root), "?%u.bagId", i + 1);

      len = sizeof (oid);
      result = asn1_read_value (c2, root, oid, &len);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      /* Read the Bag type
       */
      bag_type = oid2bag (oid);

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

      /* Read the Bag Value
       */

      snprintf (root, sizeof (root), "?%u.bagValue", i + 1);

      result = _gnutls_x509_read_value (c2, root, &bag->element[i].data, 0);
      if (result < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

      if (bag_type == GNUTLS_BAG_CERTIFICATE || bag_type == GNUTLS_BAG_CRL
	  || bag_type == GNUTLS_BAG_SECRET)
	{
	  gnutls_datum_t tmp = bag->element[i].data;

	  result =
	    _pkcs12_decode_crt_bag (bag_type, &tmp, &bag->element[i].data);
	  if (result < 0)
	    {
	      gnutls_assert ();
	      goto cleanup;
	    }

	  _gnutls_free_datum (&tmp);
	}

      /* read the bag attributes
       */
      snprintf (root, sizeof (root), "?%u.bagAttributes", i + 1);

      result = asn1_number_of_elements (c2, root, &attributes);
      if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      if (attributes < 0)
	attributes = 1;

      if (result != ASN1_ELEMENT_NOT_FOUND)
	for (j = 0; j < attributes; j++)
	  {

	    snprintf (root, sizeof (root), "?%u.bagAttributes.?%u", i + 1,
		      j + 1);

	    result =
	      _gnutls_x509_decode_and_read_attribute (c2, root, oid,
						      sizeof (oid), &attr_val,
						      1, 0);

	    if (result < 0)
	      {
		gnutls_assert ();
		continue;	/* continue in case we find some known attributes */
	      }

	    if (strcmp (oid, KEY_ID_OID) == 0)
	      {
		size = attr_val.size;

		result =
		  _gnutls_x509_decode_octet_string (NULL, attr_val.data, size,
						    attr_val.data, &size);
		attr_val.size = size;
		if (result < 0)
		  {
		    _gnutls_free_datum (&attr_val);
		    gnutls_assert ();
		    _gnutls_x509_log
		      ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
		    continue;
		  }
		bag->element[i].local_key_id = attr_val;
	      }
	    else if (strcmp (oid, FRIENDLY_NAME_OID) == 0)
	      {
		size = attr_val.size;
		result =
		  _gnutls_x509_decode_octet_string ("BMPString",
						    attr_val.data, size,
						    attr_val.data, &size);
		attr_val.size = size;
		if (result < 0)
		  {
		    _gnutls_free_datum (&attr_val);
		    gnutls_assert ();
		    _gnutls_x509_log
		      ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
		    continue;
		  }
		bag->element[i].friendly_name =
		  ucs2_to_ascii (attr_val.data, attr_val.size);
	      }
	    else
	      {
		_gnutls_free_datum (&attr_val);
		_gnutls_x509_log
		  ("Unknown PKCS12 Bag Attribute OID '%s'\n", oid);
	      }
	  }


      bag->element[i].type = bag_type;

    }

  asn1_delete_structure (&c2);


  return 0;

cleanup:
  if (c2)
    asn1_delete_structure (&c2);
  return result;

}