Beispiel #1
0
/**
 * asn1_create_element:
 * @definitions: pointer to the structure returned by "parser_asn1" function
 * @source_name: the name of the type of the new structure (must be
 *   inside p_structure).
 * @element: pointer to the structure created.
 *
 * Creates a structure of type @source_name.  Example using
 *  "pkix.asn":
 *
 * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr);
 *
 * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if
 *   @source_name is not known.
 **/
asn1_retCode
asn1_create_element (ASN1_TYPE definitions, const char *source_name,
		     ASN1_TYPE * element)
{
  ASN1_TYPE dest_node;
  int res;

  dest_node = _asn1_copy_structure2 (definitions, source_name);

  if (dest_node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  _asn1_set_name (dest_node, "");

  res = _asn1_expand_identifier (&dest_node, definitions);
  _asn1_type_choice_config (dest_node);

  *element = dest_node;

  return res;
}
Beispiel #2
0
static asn1_retCode
_asn1_expand_identifier (ASN1_TYPE * node, ASN1_TYPE root)
{
  ASN1_TYPE p, p2, p3;
  char name2[ASN1_MAX_NAME_SIZE + 2];
  int move;

  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  p = *node;
  move = DOWN;

  while (!((p == *node) && (move == UP)))
    {
      if (move != UP)
	{
	  if (type_field (p->type) == TYPE_IDENTIFIER)
	    {
	      _asn1_str_cpy (name2, sizeof (name2), root->name);
	      _asn1_str_cat (name2, sizeof (name2), ".");
	      _asn1_str_cat (name2, sizeof (name2), p->value);
	      p2 = _asn1_copy_structure2 (root, name2);
	      if (p2 == NULL)
		{
		  return ASN1_IDENTIFIER_NOT_FOUND;
		}
	      _asn1_set_name (p2, p->name);
	      p2->right = p->right;
	      p2->left = p->left;
	      if (p->right)
		p->right->left = p2;
	      p3 = p->down;
	      if (p3)
		{
		  while (p3->right)
		    p3 = p3->right;
		  _asn1_set_right (p3, p2->down);
		  _asn1_set_down (p2, p->down);
		}

	      p3 = _asn1_find_left (p);
	      if (p3)
		_asn1_set_right (p3, p2);
	      else
		{
		  p3 = _asn1_find_up (p);
		  if (p3)
		    _asn1_set_down (p3, p2);
		  else
		    {
		      p2->left = NULL;
		    }
		}

	      if (p->type & CONST_SIZE)
		p2->type |= CONST_SIZE;
	      if (p->type & CONST_TAG)
		p2->type |= CONST_TAG;
	      if (p->type & CONST_OPTION)
		p2->type |= CONST_OPTION;
	      if (p->type & CONST_DEFAULT)
		p2->type |= CONST_DEFAULT;
	      if (p->type & CONST_SET)
		p2->type |= CONST_SET;
	      if (p->type & CONST_NOT_USED)
		p2->type |= CONST_NOT_USED;

	      if (p == *node)
		*node = p2;
	      _asn1_remove_node (p);
	      p = p2;
	      move = DOWN;
	      continue;
	    }
	  move = DOWN;
	}
      else
	move = RIGHT;

      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}

      if (p == *node)
	{
	  move = UP;
	  continue;
	}

      if (move == RIGHT)
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }

  return ASN1_SUCCESS;
}
Beispiel #3
0
/**
 * asn1_array2tree:
 * @array: specify the array that contains ASN.1 declarations
 * @definitions: return the pointer to the structure created by
 *   *ARRAY ASN.1 declarations
 * @errorDescription: return the error description.
 *
 * Creates the structures needed to manage the ASN.1 definitions.
 * @array is a vector created by asn1_parser2array().
 *
 * Returns: %ASN1_SUCCESS if structure was created correctly,
 *   %ASN1_ELEMENT_NOT_EMPTY if *@definitions not ASN1_TYPE_EMPTY,
 *   %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an identifier
 *   that is not defined (see @errorDescription for more information),
 *   %ASN1_ARRAY_ERROR if the array pointed by @array is wrong.
 **/
asn1_retCode
asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
		 char *errorDescription)
{
  ASN1_TYPE p, p_last = NULL;
  unsigned long k;
  int move;
  asn1_retCode result;


  if (*definitions != ASN1_TYPE_EMPTY)
    return ASN1_ELEMENT_NOT_EMPTY;

  move = UP;

  k = 0;
  while (array[k].value || array[k].type || array[k].name)
    {
      p = _asn1_add_node (array[k].type & (~CONST_DOWN));
      if (array[k].name)
	_asn1_set_name (p, array[k].name);
      if (array[k].value)
	_asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);

      if (*definitions == NULL)
	*definitions = p;

      if (move == DOWN)
	_asn1_set_down (p_last, p);
      else if (move == RIGHT)
	_asn1_set_right (p_last, p);

      p_last = p;

      if (array[k].type & CONST_DOWN)
	move = DOWN;
      else if (array[k].type & CONST_RIGHT)
	move = RIGHT;
      else
	{
	  while (1)
	    {
	      if (p_last == *definitions)
		break;

	      p_last = _asn1_find_up (p_last);

	      if (p_last == NULL)
		break;

	      if (p_last->type & CONST_RIGHT)
		{
		  p_last->type &= ~CONST_RIGHT;
		  move = RIGHT;
		  break;
		}
	    }			/* while */
	}
      k++;
    }				/* while */

  if (p_last == *definitions)
    {
      result = _asn1_check_identifier (*definitions);
      if (result == ASN1_SUCCESS)
	{
	  _asn1_change_integer_value (*definitions);
	  _asn1_expand_object_id (*definitions);
	}
    }
  else
    {
      result = ASN1_ARRAY_ERROR;
    }

  if (errorDescription != NULL)
    {
      if (result == ASN1_IDENTIFIER_NOT_FOUND)
	{
	  Estrcpy (errorDescription, ":: identifier '");
	  Estrcat (errorDescription, _asn1_identifierMissing);
	  Estrcat (errorDescription, "' not found");
	}
      else
	errorDescription[0] = 0;
    }

  if (result != ASN1_SUCCESS)
    {
      _asn1_delete_list_and_nodes ();
      *definitions = ASN1_TYPE_EMPTY;
    }
  else
    _asn1_delete_list ();

  return result;
}
Beispiel #4
0
ASN1_TYPE
_asn1_copy_structure3 (ASN1_TYPE source_node)
{
  ASN1_TYPE dest_node, p_s, p_d, p_d_prev;
  int move;

  if (source_node == NULL)
    return NULL;

  dest_node = _asn1_add_node_only (source_node->type);

  p_s = source_node;
  p_d = dest_node;

  move = DOWN;

  do
    {
      if (move != UP)
	{
	  if (p_s->name)
	    _asn1_set_name (p_d, p_s->name);
	  if (p_s->value)
	    _asn1_set_value (p_d, p_s->value, p_s->value_len);
	  move = DOWN;
	}
      else
	move = RIGHT;

      if (move == DOWN)
	{
	  if (p_s->down)
	    {
	      p_s = p_s->down;
	      p_d_prev = p_d;
	      p_d = _asn1_add_node_only (p_s->type);
	      _asn1_set_down (p_d_prev, p_d);
	    }
	  else
	    move = RIGHT;
	}

      if (p_s == source_node)
	break;

      if (move == RIGHT)
	{
	  if (p_s->right)
	    {
	      p_s = p_s->right;
	      p_d_prev = p_d;
	      p_d = _asn1_add_node_only (p_s->type);
	      _asn1_set_right (p_d_prev, p_d);
	    }
	  else
	    move = UP;
	}
      if (move == UP)
	{
	  p_s = _asn1_find_up (p_s);
	  p_d = _asn1_find_up (p_d);
	}
    }
  while (p_s != source_node);

  return dest_node;
}
asn1_retCode
_asn1_expand_object_id (ASN1_TYPE node)
{
  ASN1_TYPE p, p2, p3, p4, p5;
  char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
  int move, tlen;

  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  _asn1_str_cpy (name_root, sizeof (name_root), node->name);

  p = node;
  move = DOWN;

  while (!((p == node) && (move == UP)))
    {
      if (move != UP)
	{
	  if ((type_field (p->type) == TYPE_OBJECT_ID)
	      && (p->type & CONST_ASSIGN))
	    {
	      p2 = p->down;
	      if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
		{
		  if (p2->value && !isdigit (p2->value[0]))
		    {
		      _asn1_str_cpy (name2, sizeof (name2), name_root);
		      _asn1_str_cat (name2, sizeof (name2), ".");
		      _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
		      p3 = asn1_find_node (node, name2);
		      if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
			  !(p3->type & CONST_ASSIGN))
			return ASN1_ELEMENT_NOT_FOUND;
		      _asn1_set_down (p, p2->right);
		      _asn1_remove_node (p2);
		      p2 = p;
		      p4 = p3->down;
		      while (p4)
			{
			  if (type_field (p4->type) == TYPE_CONSTANT)
			    {
			      p5 = _asn1_add_node_only (TYPE_CONSTANT);
			      _asn1_set_name (p5, p4->name);
			      tlen = _asn1_strlen (p4->value);
			      if (tlen > 0)
				_asn1_set_value (p5, p4->value, tlen + 1);
			      if (p2 == p)
				{
				  _asn1_set_right (p5, p->down);
				  _asn1_set_down (p, p5);
				}
			      else
				{
				  _asn1_set_right (p5, p2->right);
				  _asn1_set_right (p2, p5);
				}
			      p2 = p5;
			    }
			  p4 = p4->right;
			}
		      move = DOWN;
		      continue;
		    }
		}
	    }
	  move = DOWN;
	}
      else
	move = RIGHT;

      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}

      if (p == node)
	{
	  move = UP;
	  continue;
	}

      if (move == RIGHT)
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }


  /*******************************/
  /*       expand DEFAULT        */
  /*******************************/
  p = node;
  move = DOWN;

  while (!((p == node) && (move == UP)))
    {
      if (move != UP)
	{
	  if ((type_field (p->type) == TYPE_OBJECT_ID) &&
	      (p->type & CONST_DEFAULT))
	    {
	      p2 = p->down;
	      if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
		{
		  _asn1_str_cpy (name2, sizeof (name2), name_root);
		  _asn1_str_cat (name2, sizeof (name2), ".");
		  _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
		  p3 = asn1_find_node (node, name2);
		  if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
		      !(p3->type & CONST_ASSIGN))
		    return ASN1_ELEMENT_NOT_FOUND;
		  p4 = p3->down;
		  name2[0] = 0;
		  while (p4)
		    {
		      if (type_field (p4->type) == TYPE_CONSTANT)
			{
			  if (name2[0])
			    _asn1_str_cat (name2, sizeof (name2), ".");
			  _asn1_str_cat (name2, sizeof (name2),
					 (char *) p4->value);
			}
		      p4 = p4->right;
		    }
		  tlen = strlen (name2);
		  if (tlen > 0)
		    _asn1_set_value (p2, name2, tlen + 1);
		}
	    }
	  move = DOWN;
	}
      else
	move = RIGHT;

      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}

      if (p == node)
	{
	  move = UP;
	  continue;
	}

      if (move == RIGHT)
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }

  return ASN1_SUCCESS;
}