Blame lib/minitasn1/structure.c

Packit Service 4684c1
/*
Packit Service 4684c1
 * Copyright (C) 2002-2014 Free Software Foundation, Inc.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This file is part of LIBTASN1.
Packit Service 4684c1
 *
Packit Service 4684c1
 * The LIBTASN1 library is free software; you can redistribute it
Packit Service 4684c1
 * and/or modify it under the terms of the GNU Lesser General Public
Packit Service 4684c1
 * License as published by the Free Software Foundation; either
Packit Service 4684c1
 * version 2.1 of the License, or (at your option) any later version.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This library is distributed in the hope that it will be useful, but
Packit Service 4684c1
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 4684c1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 4684c1
 * Lesser General Public License for more details.
Packit Service 4684c1
 *
Packit Service 4684c1
 * You should have received a copy of the GNU Lesser General Public
Packit Service 4684c1
 * License along with this library; if not, write to the Free Software
Packit Service 4684c1
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 4684c1
 * 02110-1301, USA
Packit Service 4684c1
 */
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/*****************************************************/
Packit Service 4684c1
/* File: structure.c                                 */
Packit Service 4684c1
/* Description: Functions to create and delete an    */
Packit Service 4684c1
/*  ASN1 tree.                                       */
Packit Service 4684c1
/*****************************************************/
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
#include <int.h>
Packit Service 4684c1
#include <structure.h>
Packit Service 4684c1
#include "parser_aux.h"
Packit Service 4684c1
#include <gstr.h>
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
extern char _asn1_identifierMissing[];
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/******************************************************/
Packit Service 4684c1
/* Function : _asn1_add_single_node                     */
Packit Service 4684c1
/* Description: creates a new NODE_ASN element.       */
Packit Service 4684c1
/* Parameters:                                        */
Packit Service 4684c1
/*   type: type of the new element (see ASN1_ETYPE_         */
Packit Service 4684c1
/*         and CONST_ constants).                     */
Packit Service 4684c1
/* Return: pointer to the new element.                */
Packit Service 4684c1
/******************************************************/
Packit Service 4684c1
asn1_node
Packit Service 4684c1
_asn1_add_single_node (unsigned int type)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node punt;
Packit Service 4684c1
Packit Service 4684c1
  punt = calloc (1, sizeof (struct asn1_node_st));
Packit Service 4684c1
  if (punt == NULL)
Packit Service 4684c1
    return NULL;
Packit Service 4684c1
Packit Service 4684c1
  punt->type = type;
Packit Service 4684c1
Packit Service 4684c1
  return punt;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/******************************************************************/
Packit Service 4684c1
/* Function : _asn1_find_left                                     */
Packit Service 4684c1
/* Description: returns the NODE_ASN element with RIGHT field that*/
Packit Service 4684c1
/*              points the element NODE.                          */
Packit Service 4684c1
/* Parameters:                                                    */
Packit Service 4684c1
/*   node: NODE_ASN element pointer.                              */
Packit Service 4684c1
/* Return: NULL if not found.                                     */
Packit Service 4684c1
/******************************************************************/
Packit Service 4684c1
asn1_node
Packit Service 4684c1
_asn1_find_left (asn1_node_const node)
Packit Service 4684c1
{
Packit Service 4684c1
  if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
Packit Service 4684c1
    return NULL;
Packit Service 4684c1
Packit Service 4684c1
  return node->left;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
int
Packit Service 4684c1
_asn1_create_static_structure (asn1_node_const pointer, char *output_file_name,
Packit Service 4684c1
			       char *vector_name)
Packit Service 4684c1
{
Packit Service 4684c1
  FILE *file;
Packit Service 4684c1
  asn1_node_const p;
Packit Service 4684c1
  unsigned long t;
Packit Service 4684c1
Packit Service 4684c1
  file = fopen (output_file_name, "w");
Packit Service 4684c1
Packit Service 4684c1
  if (file == NULL)
Packit Service 4684c1
    return ASN1_FILE_NOT_FOUND;
Packit Service 4684c1
Packit Service 4684c1
  fprintf (file, "#if HAVE_CONFIG_H\n");
Packit Service 4684c1
  fprintf (file, "# include \"config.h\"\n");
Packit Service 4684c1
  fprintf (file, "#endif\n\n");
Packit Service 4684c1
Packit Service 4684c1
  fprintf (file, "#include <libtasn1.h>\n\n");
Packit Service 4684c1
Packit Service 4684c1
  fprintf (file, "const asn1_static_node %s[] = {\n", vector_name);
Packit Service 4684c1
Packit Service 4684c1
  p = pointer;
Packit Service 4684c1
Packit Service 4684c1
  while (p)
Packit Service 4684c1
    {
Packit Service 4684c1
      fprintf (file, "  { ");
Packit Service 4684c1
Packit Service 4684c1
      if (p->name[0] != 0)
Packit Service 4684c1
	fprintf (file, "\"%s\", ", p->name);
Packit Service 4684c1
      else
Packit Service 4684c1
	fprintf (file, "NULL, ");
Packit Service 4684c1
Packit Service 4684c1
      t = p->type;
Packit Service 4684c1
      if (p->down)
Packit Service 4684c1
	t |= CONST_DOWN;
Packit Service 4684c1
      if (p->right)
Packit Service 4684c1
	t |= CONST_RIGHT;
Packit Service 4684c1
Packit Service 4684c1
      fprintf (file, "%lu, ", t);
Packit Service 4684c1
Packit Service 4684c1
      if (p->value)
Packit Service 4684c1
	fprintf (file, "\"%s\"},\n", p->value);
Packit Service 4684c1
      else
Packit Service 4684c1
	fprintf (file, "NULL },\n");
Packit Service 4684c1
Packit Service 4684c1
      if (p->down)
Packit Service 4684c1
	{
Packit Service 4684c1
	  p = p->down;
Packit Service 4684c1
	}
Packit Service 4684c1
      else if (p->right)
Packit Service 4684c1
	{
Packit Service 4684c1
	  p = p->right;
Packit Service 4684c1
	}
Packit Service 4684c1
      else
Packit Service 4684c1
	{
Packit Service 4684c1
	  while (1)
Packit Service 4684c1
	    {
Packit Service 4684c1
	      p = _asn1_find_up (p);
Packit Service 4684c1
	      if (p == pointer)
Packit Service 4684c1
		{
Packit Service 4684c1
		  p = NULL;
Packit Service 4684c1
		  break;
Packit Service 4684c1
		}
Packit Service 4684c1
	      if (p->right)
Packit Service 4684c1
		{
Packit Service 4684c1
		  p = p->right;
Packit Service 4684c1
		  break;
Packit Service 4684c1
		}
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  fprintf (file, "  { NULL, 0, NULL }\n};\n");
Packit Service 4684c1
Packit Service 4684c1
  fclose (file);
Packit Service 4684c1
Packit Service 4684c1
  return ASN1_SUCCESS;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_array2tree:
Packit Service 4684c1
 * @array: specify the array that contains ASN.1 declarations
Packit Service 4684c1
 * @definitions: return the pointer to the structure created by
Packit Service 4684c1
 *   *ARRAY ASN.1 declarations
Packit Service 4684c1
 * @errorDescription: return the error description.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Creates the structures needed to manage the ASN.1 definitions.
Packit Service 4684c1
 * @array is a vector created by asn1_parser2array().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %ASN1_SUCCESS if structure was created correctly,
Packit Service 4684c1
 *   %ASN1_ELEMENT_NOT_EMPTY if *@definitions not NULL,
Packit Service 4684c1
 *   %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an identifier
Packit Service 4684c1
 *   that is not defined (see @errorDescription for more information),
Packit Service 4684c1
 *   %ASN1_ARRAY_ERROR if the array pointed by @array is wrong.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
Packit Service 4684c1
		 char *errorDescription)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node p, p_last = NULL;
Packit Service 4684c1
  unsigned long k;
Packit Service 4684c1
  int move;
Packit Service 4684c1
  int result;
Packit Service 4684c1
  unsigned int type;
Packit Service 4684c1
  list_type *e_list = NULL;
Packit Service 4684c1
Packit Service 4684c1
  if (errorDescription)
Packit Service 4684c1
    errorDescription[0] = 0;
Packit Service 4684c1
Packit Service 4684c1
  if (*definitions != NULL)
Packit Service 4684c1
    return ASN1_ELEMENT_NOT_EMPTY;
Packit Service 4684c1
Packit Service 4684c1
  move = UP;
Packit Service 4684c1
Packit Service 4684c1
  for (k = 0; array[k].value || array[k].type || array[k].name; k++)
Packit Service 4684c1
    {
Packit Service 4684c1
      type = convert_old_type (array[k].type);
Packit Service 4684c1
Packit Service 4684c1
      p = _asn1_add_static_node (&e_list, type & (~CONST_DOWN));
Packit Service 4684c1
      if (array[k].name)
Packit Service 4684c1
	_asn1_set_name (p, array[k].name);
Packit Service 4684c1
      if (array[k].value)
Packit Service 4684c1
	_asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
Packit Service 4684c1
Packit Service 4684c1
      if (*definitions == NULL)
Packit Service 4684c1
	*definitions = p;
Packit Service 4684c1
Packit Service 4684c1
      if (move == DOWN)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if (p_last && p_last->down)
Packit Service 4684c1
	      _asn1_delete_structure (e_list, &p_last->down, 0);
Packit Service 4684c1
	  _asn1_set_down (p_last, p);
Packit Service 4684c1
	}
Packit Service 4684c1
      else if (move == RIGHT)
Packit Service 4684c1
        {
Packit Service 4684c1
	  if (p_last && p_last->right)
Packit Service 4684c1
	      _asn1_delete_structure (e_list, &p_last->right, 0);
Packit Service 4684c1
	  _asn1_set_right (p_last, p);
Packit Service 4684c1
        }
Packit Service 4684c1
Packit Service 4684c1
      p_last = p;
Packit Service 4684c1
Packit Service 4684c1
      if (type & CONST_DOWN)
Packit Service 4684c1
	move = DOWN;
Packit Service 4684c1
      else if (type & CONST_RIGHT)
Packit Service 4684c1
	move = RIGHT;
Packit Service 4684c1
      else
Packit Service 4684c1
	{
Packit Service 4684c1
	  while (p_last != *definitions)
Packit Service 4684c1
	    {
Packit Service 4684c1
	      p_last = _asn1_find_up (p_last);
Packit Service 4684c1
Packit Service 4684c1
	      if (p_last == NULL)
Packit Service 4684c1
		break;
Packit Service 4684c1
Packit Service 4684c1
	      if (p_last->type & CONST_RIGHT)
Packit Service 4684c1
		{
Packit Service 4684c1
		  p_last->type &= ~CONST_RIGHT;
Packit Service 4684c1
		  move = RIGHT;
Packit Service 4684c1
		  break;
Packit Service 4684c1
		}
Packit Service 4684c1
	    }			/* while */
Packit Service 4684c1
	}
Packit Service 4684c1
    }				/* while */
Packit Service 4684c1
Packit Service 4684c1
  if (p_last == *definitions)
Packit Service 4684c1
    {
Packit Service 4684c1
      result = _asn1_check_identifier (*definitions);
Packit Service 4684c1
      if (result == ASN1_SUCCESS)
Packit Service 4684c1
	{
Packit Service 4684c1
	  _asn1_change_integer_value (*definitions);
Packit Service 4684c1
	  result = _asn1_expand_object_id (&e_list, *definitions);
Packit Service 4684c1
	}
Packit Service 4684c1
    }
Packit Service 4684c1
  else
Packit Service 4684c1
    {
Packit Service 4684c1
      result = ASN1_ARRAY_ERROR;
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  if (errorDescription != NULL)
Packit Service 4684c1
    {
Packit Service 4684c1
      if (result == ASN1_IDENTIFIER_NOT_FOUND)
Packit Service 4684c1
	{
Packit Service 4684c1
	  Estrcpy (errorDescription, ":: identifier '");
Packit Service 4684c1
	  Estrcat (errorDescription, _asn1_identifierMissing);
Packit Service 4684c1
	  Estrcat (errorDescription, "' not found");
Packit Service 4684c1
	}
Packit Service 4684c1
      else
Packit Service 4684c1
	errorDescription[0] = 0;
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  if (result != ASN1_SUCCESS)
Packit Service 4684c1
    {
Packit Service 4684c1
      _asn1_delete_list_and_nodes (e_list);
Packit Service 4684c1
      *definitions = NULL;
Packit Service 4684c1
    }
Packit Service 4684c1
  else
Packit Service 4684c1
    _asn1_delete_list (e_list);
Packit Service 4684c1
Packit Service 4684c1
  return result;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_delete_structure:
Packit Service 4684c1
 * @structure: pointer to the structure that you want to delete.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Deletes the structure *@structure.  At the end, *@structure is set
Packit Service 4684c1
 * to NULL.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
Packit Service 4684c1
 *   *@structure was NULL.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
asn1_delete_structure (asn1_node * structure)
Packit Service 4684c1
{
Packit Service 4684c1
  return _asn1_delete_structure (NULL, structure, 0);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_delete_structure2:
Packit Service 4684c1
 * @structure: pointer to the structure that you want to delete.
Packit Service 4684c1
 * @flags: additional flags (see %ASN1_DELETE_FLAG)
Packit Service 4684c1
 *
Packit Service 4684c1
 * Deletes the structure *@structure.  At the end, *@structure is set
Packit Service 4684c1
 * to NULL.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
Packit Service 4684c1
 *   *@structure was NULL.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
asn1_delete_structure2 (asn1_node * structure, unsigned int flags)
Packit Service 4684c1
{
Packit Service 4684c1
  return _asn1_delete_structure (NULL, structure, flags);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
int
Packit Service 4684c1
_asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int flags)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node p, p2, p3;
Packit Service 4684c1
Packit Service 4684c1
  if (*structure == NULL)
Packit Service 4684c1
    return ASN1_ELEMENT_NOT_FOUND;
Packit Service 4684c1
Packit Service 4684c1
  p = *structure;
Packit Service 4684c1
  while (p)
Packit Service 4684c1
    {
Packit Service 4684c1
      if (p->down)
Packit Service 4684c1
	{
Packit Service 4684c1
	  p = p->down;
Packit Service 4684c1
	}
Packit Service 4684c1
      else
Packit Service 4684c1
	{			/* no down */
Packit Service 4684c1
	  p2 = p->right;
Packit Service 4684c1
	  if (p != *structure)
Packit Service 4684c1
	    {
Packit Service 4684c1
	      p3 = _asn1_find_up (p);
Packit Service 4684c1
	      _asn1_set_down (p3, p2);
Packit Service 4684c1
	      if (e_list)
Packit Service 4684c1
		_asn1_delete_node_from_list (e_list, p);
Packit Service 4684c1
	      _asn1_remove_node (p, flags);
Packit Service 4684c1
	      p = p3;
Packit Service 4684c1
	    }
Packit Service 4684c1
	  else
Packit Service 4684c1
	    {			/* p==root */
Packit Service 4684c1
	      p3 = _asn1_find_left (p);
Packit Service 4684c1
	      if (!p3)
Packit Service 4684c1
		{
Packit Service 4684c1
		  p3 = _asn1_find_up (p);
Packit Service 4684c1
		  if (p3)
Packit Service 4684c1
		    _asn1_set_down (p3, p2);
Packit Service 4684c1
		  else
Packit Service 4684c1
		    {
Packit Service 4684c1
		      if (p->right)
Packit Service 4684c1
			p->right->left = NULL;
Packit Service 4684c1
		    }
Packit Service 4684c1
		}
Packit Service 4684c1
	      else
Packit Service 4684c1
		_asn1_set_right (p3, p2);
Packit Service 4684c1
	      if (e_list)
Packit Service 4684c1
		_asn1_delete_node_from_list (e_list, p);
Packit Service 4684c1
	      _asn1_remove_node (p, flags);
Packit Service 4684c1
	      p = NULL;
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  *structure = NULL;
Packit Service 4684c1
  return ASN1_SUCCESS;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_delete_element:
Packit Service 4684c1
 * @structure: pointer to the structure that contains the element you
Packit Service 4684c1
 *   want to delete.
Packit Service 4684c1
 * @element_name: element's name you want to delete.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Deletes the element named *@element_name inside *@structure.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
Packit Service 4684c1
 *   the @element_name was not found.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
asn1_delete_element (asn1_node structure, const char *element_name)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node p2, p3, source_node;
Packit Service 4684c1
Packit Service 4684c1
  source_node = asn1_find_node (structure, element_name);
Packit Service 4684c1
Packit Service 4684c1
  if (source_node == NULL)
Packit Service 4684c1
    return ASN1_ELEMENT_NOT_FOUND;
Packit Service 4684c1
Packit Service 4684c1
  p2 = source_node->right;
Packit Service 4684c1
  p3 = _asn1_find_left (source_node);
Packit Service 4684c1
  if (!p3)
Packit Service 4684c1
    {
Packit Service 4684c1
      p3 = _asn1_find_up (source_node);
Packit Service 4684c1
      if (p3)
Packit Service 4684c1
	_asn1_set_down (p3, p2);
Packit Service 4684c1
      else if (source_node->right)
Packit Service 4684c1
	source_node->right->left = NULL;
Packit Service 4684c1
    }
Packit Service 4684c1
  else
Packit Service 4684c1
    _asn1_set_right (p3, p2);
Packit Service 4684c1
Packit Service 4684c1
  return asn1_delete_structure (&source_node);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#ifndef __clang_analyzer__
Packit Service 4684c1
asn1_node
Packit Service 4684c1
_asn1_copy_structure3 (asn1_node_const source_node)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node_const p_s;
Packit Service 4684c1
  asn1_node dest_node, p_d, p_d_prev;
Packit Service 4684c1
  int move;
Packit Service 4684c1
Packit Service 4684c1
  if (source_node == NULL)
Packit Service 4684c1
    return NULL;
Packit Service 4684c1
Packit Service 4684c1
  dest_node = _asn1_add_single_node (source_node->type);
Packit Service 4684c1
Packit Service 4684c1
  p_s = source_node;
Packit Service 4684c1
  p_d = dest_node;
Packit Service 4684c1
Packit Service 4684c1
  move = DOWN;
Packit Service 4684c1
Packit Service 4684c1
  do
Packit Service 4684c1
    {
Packit Service 4684c1
      if (move != UP)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if (p_s->name[0] != 0)
Packit Service 4684c1
	    _asn1_cpy_name (p_d, p_s);
Packit Service 4684c1
	  if (p_s->value)
Packit Service 4684c1
	    _asn1_set_value (p_d, p_s->value, p_s->value_len);
Packit Service 4684c1
	  if (p_s->down)
Packit Service 4684c1
	    {
Packit Service 4684c1
	      p_s = p_s->down;
Packit Service 4684c1
	      p_d_prev = p_d;
Packit Service 4684c1
	      p_d = _asn1_add_single_node (p_s->type);
Packit Service 4684c1
	      _asn1_set_down (p_d_prev, p_d);
Packit Service 4684c1
	      continue;
Packit Service 4684c1
	    }
Packit Service 4684c1
	  p_d->start = p_s->start;
Packit Service 4684c1
	  p_d->end = p_s->end;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (p_s == source_node)
Packit Service 4684c1
	break;
Packit Service 4684c1
Packit Service 4684c1
      if (p_s->right)
Packit Service 4684c1
	{
Packit Service 4684c1
	  move = RIGHT;
Packit Service 4684c1
	  p_s = p_s->right;
Packit Service 4684c1
	  p_d_prev = p_d;
Packit Service 4684c1
	  p_d = _asn1_add_single_node (p_s->type);
Packit Service 4684c1
	  _asn1_set_right (p_d_prev, p_d);
Packit Service 4684c1
	}
Packit Service 4684c1
      else
Packit Service 4684c1
	{
Packit Service 4684c1
	  move = UP;
Packit Service 4684c1
	  p_s = _asn1_find_up (p_s);
Packit Service 4684c1
	  p_d = _asn1_find_up (p_d);
Packit Service 4684c1
	}
Packit Service 4684c1
    }
Packit Service 4684c1
  while (p_s != source_node);
Packit Service 4684c1
  return dest_node;
Packit Service 4684c1
}
Packit Service 4684c1
#else
Packit Service 4684c1
Packit Service 4684c1
/* Non-production code */
Packit Service 4684c1
asn1_node
Packit Service 4684c1
_asn1_copy_structure3 (asn1_node_const source_node)
Packit Service 4684c1
{
Packit Service 4684c1
  return NULL;
Packit Service 4684c1
}
Packit Service 4684c1
#endif /* __clang_analyzer__ */
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
static asn1_node
Packit Service 4684c1
_asn1_copy_structure2 (asn1_node_const root, const char *source_name)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node source_node;
Packit Service 4684c1
Packit Service 4684c1
  source_node = asn1_find_node (root, source_name);
Packit Service 4684c1
Packit Service 4684c1
  return _asn1_copy_structure3 (source_node);
Packit Service 4684c1
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
static int
Packit Service 4684c1
_asn1_type_choice_config (asn1_node node)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node p, p2, p3, p4;
Packit Service 4684c1
  int move, tlen;
Packit Service 4684c1
Packit Service 4684c1
  if (node == NULL)
Packit Service 4684c1
    return ASN1_ELEMENT_NOT_FOUND;
Packit Service 4684c1
Packit Service 4684c1
  p = node;
Packit Service 4684c1
  move = DOWN;
Packit Service 4684c1
Packit Service 4684c1
  while (!((p == node) && (move == UP)))
Packit Service 4684c1
    {
Packit Service 4684c1
      if (move != UP)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if ((type_field (p->type) == ASN1_ETYPE_CHOICE)
Packit Service 4684c1
	      && (p->type & CONST_TAG))
Packit Service 4684c1
	    {
Packit Service 4684c1
	      p2 = p->down;
Packit Service 4684c1
	      while (p2)
Packit Service 4684c1
		{
Packit Service 4684c1
		  if (type_field (p2->type) != ASN1_ETYPE_TAG)
Packit Service 4684c1
		    {
Packit Service 4684c1
		      p2->type |= CONST_TAG;
Packit Service 4684c1
		      p3 = _asn1_find_left (p2);
Packit Service 4684c1
		      while (p3)
Packit Service 4684c1
			{
Packit Service 4684c1
			  if (type_field (p3->type) == ASN1_ETYPE_TAG)
Packit Service 4684c1
			    {
Packit Service 4684c1
			      p4 = _asn1_add_single_node (p3->type);
Packit Service 4684c1
			      tlen = _asn1_strlen (p3->value);
Packit Service 4684c1
			      if (tlen > 0)
Packit Service 4684c1
				_asn1_set_value (p4, p3->value, tlen + 1);
Packit Service 4684c1
			      _asn1_set_right (p4, p2->down);
Packit Service 4684c1
			      _asn1_set_down (p2, p4);
Packit Service 4684c1
			    }
Packit Service 4684c1
			  p3 = _asn1_find_left (p3);
Packit Service 4684c1
			}
Packit Service 4684c1
		    }
Packit Service 4684c1
		  p2 = p2->right;
Packit Service 4684c1
		}
Packit Service 4684c1
	      p->type &= ~(CONST_TAG);
Packit Service 4684c1
	      p2 = p->down;
Packit Service 4684c1
	      while (p2)
Packit Service 4684c1
		{
Packit Service 4684c1
		  p3 = p2->right;
Packit Service 4684c1
		  if (type_field (p2->type) == ASN1_ETYPE_TAG)
Packit Service 4684c1
		    asn1_delete_structure (&p2;;
Packit Service 4684c1
		  p2 = p3;
Packit Service 4684c1
		}
Packit Service 4684c1
	    }
Packit Service 4684c1
	  move = DOWN;
Packit Service 4684c1
	}
Packit Service 4684c1
      else
Packit Service 4684c1
	move = RIGHT;
Packit Service 4684c1
Packit Service 4684c1
      if (move == DOWN)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if (p->down)
Packit Service 4684c1
	    p = p->down;
Packit Service 4684c1
	  else
Packit Service 4684c1
	    move = RIGHT;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (p == node)
Packit Service 4684c1
	{
Packit Service 4684c1
	  move = UP;
Packit Service 4684c1
	  continue;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (move == RIGHT)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if (p->right)
Packit Service 4684c1
	    p = p->right;
Packit Service 4684c1
	  else
Packit Service 4684c1
	    move = UP;
Packit Service 4684c1
	}
Packit Service 4684c1
      if (move == UP)
Packit Service 4684c1
	p = _asn1_find_up (p);
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  return ASN1_SUCCESS;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
static int
Packit Service 4684c1
_asn1_expand_identifier (asn1_node * node, asn1_node_const root)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node p, p2, p3;
Packit Service 4684c1
  char name2[ASN1_MAX_NAME_SIZE + 2];
Packit Service 4684c1
  int move;
Packit Service 4684c1
Packit Service 4684c1
  if (node == NULL)
Packit Service 4684c1
    return ASN1_ELEMENT_NOT_FOUND;
Packit Service 4684c1
Packit Service 4684c1
  p = *node;
Packit Service 4684c1
  move = DOWN;
Packit Service 4684c1
Packit Service 4684c1
  while (!((p == *node) && (move == UP)))
Packit Service 4684c1
    {
Packit Service 4684c1
      if (move != UP)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
Packit Service 4684c1
	    {
Packit Service 4684c1
	      snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value);
Packit Service 4684c1
	      p2 = _asn1_copy_structure2 (root, name2);
Packit Service 4684c1
	      if (p2 == NULL)
Packit Service 4684c1
		{
Packit Service 4684c1
		  return ASN1_IDENTIFIER_NOT_FOUND;
Packit Service 4684c1
		}
Packit Service 4684c1
	      _asn1_cpy_name (p2, p);
Packit Service 4684c1
	      p2->right = p->right;
Packit Service 4684c1
	      p2->left = p->left;
Packit Service 4684c1
	      if (p->right)
Packit Service 4684c1
		p->right->left = p2;
Packit Service 4684c1
	      p3 = p->down;
Packit Service 4684c1
	      if (p3)
Packit Service 4684c1
		{
Packit Service 4684c1
		  while (p3->right)
Packit Service 4684c1
		    p3 = p3->right;
Packit Service 4684c1
		  _asn1_set_right (p3, p2->down);
Packit Service 4684c1
		  _asn1_set_down (p2, p->down);
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
	      p3 = _asn1_find_left (p);
Packit Service 4684c1
	      if (p3)
Packit Service 4684c1
		_asn1_set_right (p3, p2);
Packit Service 4684c1
	      else
Packit Service 4684c1
		{
Packit Service 4684c1
		  p3 = _asn1_find_up (p);
Packit Service 4684c1
		  if (p3)
Packit Service 4684c1
		    _asn1_set_down (p3, p2);
Packit Service 4684c1
		  else
Packit Service 4684c1
		    {
Packit Service 4684c1
		      p2->left = NULL;
Packit Service 4684c1
		    }
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
	      if (p->type & CONST_SIZE)
Packit Service 4684c1
		p2->type |= CONST_SIZE;
Packit Service 4684c1
	      if (p->type & CONST_TAG)
Packit Service 4684c1
		p2->type |= CONST_TAG;
Packit Service 4684c1
	      if (p->type & CONST_OPTION)
Packit Service 4684c1
		p2->type |= CONST_OPTION;
Packit Service 4684c1
	      if (p->type & CONST_DEFAULT)
Packit Service 4684c1
		p2->type |= CONST_DEFAULT;
Packit Service 4684c1
	      if (p->type & CONST_SET)
Packit Service 4684c1
		p2->type |= CONST_SET;
Packit Service 4684c1
	      if (p->type & CONST_NOT_USED)
Packit Service 4684c1
		p2->type |= CONST_NOT_USED;
Packit Service 4684c1
Packit Service 4684c1
	      if (p == *node)
Packit Service 4684c1
		*node = p2;
Packit Service 4684c1
	      _asn1_remove_node (p, 0);
Packit Service 4684c1
	      p = p2;
Packit Service 4684c1
	      move = DOWN;
Packit Service 4684c1
	      continue;
Packit Service 4684c1
	    }
Packit Service 4684c1
	  move = DOWN;
Packit Service 4684c1
	}
Packit Service 4684c1
      else
Packit Service 4684c1
	move = RIGHT;
Packit Service 4684c1
Packit Service 4684c1
      if (move == DOWN)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if (p->down)
Packit Service 4684c1
	    p = p->down;
Packit Service 4684c1
	  else
Packit Service 4684c1
	    move = RIGHT;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (p == *node)
Packit Service 4684c1
	{
Packit Service 4684c1
	  move = UP;
Packit Service 4684c1
	  continue;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (move == RIGHT)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if (p->right)
Packit Service 4684c1
	    p = p->right;
Packit Service 4684c1
	  else
Packit Service 4684c1
	    move = UP;
Packit Service 4684c1
	}
Packit Service 4684c1
      if (move == UP)
Packit Service 4684c1
	p = _asn1_find_up (p);
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  return ASN1_SUCCESS;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_create_element:
Packit Service 4684c1
 * @definitions: pointer to the structure returned by "parser_asn1" function
Packit Service 4684c1
 * @source_name: the name of the type of the new structure (must be
Packit Service 4684c1
 *   inside p_structure).
Packit Service 4684c1
 * @element: pointer to the structure created.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Creates a structure of type @source_name.  Example using
Packit Service 4684c1
 *  "pkix.asn":
Packit Service 4684c1
 *
Packit Service 4684c1
 * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr);
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if
Packit Service 4684c1
 *   @source_name is not known.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
asn1_create_element (asn1_node_const definitions, const char *source_name,
Packit Service 4684c1
		     asn1_node * element)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node dest_node;
Packit Service 4684c1
  int res;
Packit Service 4684c1
Packit Service 4684c1
  dest_node = _asn1_copy_structure2 (definitions, source_name);
Packit Service 4684c1
Packit Service 4684c1
  if (dest_node == NULL)
Packit Service 4684c1
    return ASN1_ELEMENT_NOT_FOUND;
Packit Service 4684c1
Packit Service 4684c1
  _asn1_set_name (dest_node, "");
Packit Service 4684c1
Packit Service 4684c1
  res = _asn1_expand_identifier (&dest_node, definitions);
Packit Service 4684c1
  _asn1_type_choice_config (dest_node);
Packit Service 4684c1
Packit Service 4684c1
  *element = dest_node;
Packit Service 4684c1
Packit Service 4684c1
  return res;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_print_structure:
Packit Service 4684c1
 * @out: pointer to the output file (e.g. stdout).
Packit Service 4684c1
 * @structure: pointer to the structure that you want to visit.
Packit Service 4684c1
 * @name: an element of the structure
Packit Service 4684c1
 * @mode: specify how much of the structure to print, can be
Packit Service 4684c1
 *   %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
Packit Service 4684c1
 *   %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Prints on the @out file descriptor the structure's tree starting
Packit Service 4684c1
 * from the @name element inside the structure @structure.
Packit Service 4684c1
 **/
Packit Service 4684c1
void
Packit Service 4684c1
asn1_print_structure (FILE * out, asn1_node_const structure, const char *name,
Packit Service 4684c1
		      int mode)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node_const p, root;
Packit Service 4684c1
  int k, indent = 0, len, len2, len3;
Packit Service 4684c1
Packit Service 4684c1
  if (out == NULL)
Packit Service 4684c1
    return;
Packit Service 4684c1
Packit Service 4684c1
  root = asn1_find_node (structure, name);
Packit Service 4684c1
Packit Service 4684c1
  if (root == NULL)
Packit Service 4684c1
    return;
Packit Service 4684c1
Packit Service 4684c1
  p = root;
Packit Service 4684c1
  while (p)
Packit Service 4684c1
    {
Packit Service 4684c1
      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
	{
Packit Service 4684c1
	  for (k = 0; k < indent; k++)
Packit Service 4684c1
	    fprintf (out, " ");
Packit Service 4684c1
	  fprintf (out, "name:");
Packit Service 4684c1
	  if (p->name[0] != 0)
Packit Service 4684c1
	    fprintf (out, "%s  ", p->name);
Packit Service 4684c1
	  else
Packit Service 4684c1
	    fprintf (out, "NULL  ");
Packit Service 4684c1
	}
Packit Service 4684c1
      else
Packit Service 4684c1
	{
Packit Service 4684c1
	  switch (type_field (p->type))
Packit Service 4684c1
	    {
Packit Service 4684c1
	    case ASN1_ETYPE_CONSTANT:
Packit Service 4684c1
	    case ASN1_ETYPE_TAG:
Packit Service 4684c1
	    case ASN1_ETYPE_SIZE:
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    default:
Packit Service 4684c1
	      for (k = 0; k < indent; k++)
Packit Service 4684c1
		fprintf (out, " ");
Packit Service 4684c1
	      fprintf (out, "name:");
Packit Service 4684c1
	      if (p->name[0] != 0)
Packit Service 4684c1
		fprintf (out, "%s  ", p->name);
Packit Service 4684c1
	      else
Packit Service 4684c1
		fprintf (out, "NULL  ");
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (mode != ASN1_PRINT_NAME)
Packit Service 4684c1
	{
Packit Service 4684c1
	  unsigned type = type_field (p->type);
Packit Service 4684c1
	  switch (type)
Packit Service 4684c1
	    {
Packit Service 4684c1
	    case ASN1_ETYPE_CONSTANT:
Packit Service 4684c1
	      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
		fprintf (out, "type:CONST");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_TAG:
Packit Service 4684c1
	      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
		fprintf (out, "type:TAG");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_SIZE:
Packit Service 4684c1
	      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
		fprintf (out, "type:SIZE");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_DEFAULT:
Packit Service 4684c1
	      fprintf (out, "type:DEFAULT");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_IDENTIFIER:
Packit Service 4684c1
	      fprintf (out, "type:IDENTIFIER");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_ANY:
Packit Service 4684c1
	      fprintf (out, "type:ANY");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_CHOICE:
Packit Service 4684c1
	      fprintf (out, "type:CHOICE");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_DEFINITIONS:
Packit Service 4684c1
	      fprintf (out, "type:DEFINITIONS");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    CASE_HANDLED_ETYPES:
Packit Service 4684c1
	      fprintf (out, "%s", _asn1_tags[type].desc);
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    default:
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
Packit Service 4684c1
	{
Packit Service 4684c1
	  switch (type_field (p->type))
Packit Service 4684c1
	    {
Packit Service 4684c1
	    case ASN1_ETYPE_CONSTANT:
Packit Service 4684c1
	      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
		if (p->value)
Packit Service 4684c1
		  fprintf (out, "  value:%s", p->value);
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_TAG:
Packit Service 4684c1
	      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
		if (p->value)
Packit Service 4684c1
		  fprintf (out, "  value:%s", p->value);
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_SIZE:
Packit Service 4684c1
	      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
		if (p->value)
Packit Service 4684c1
		  fprintf (out, "  value:%s", p->value);
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_DEFAULT:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		fprintf (out, "  value:%s", p->value);
Packit Service 4684c1
	      else if (p->type & CONST_TRUE)
Packit Service 4684c1
		fprintf (out, "  value:TRUE");
Packit Service 4684c1
	      else if (p->type & CONST_FALSE)
Packit Service 4684c1
		fprintf (out, "  value:FALSE");
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_IDENTIFIER:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		fprintf (out, "  value:%s", p->value);
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_INTEGER:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		{
Packit Service 4684c1
		  len2 = -1;
Packit Service 4684c1
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
Packit Service 4684c1
		  fprintf (out, "  value:0x");
Packit Service 4684c1
		  if (len > 0)
Packit Service 4684c1
		    for (k = 0; k < len; k++)
Packit Service 4684c1
		      fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
Packit Service 4684c1
		}
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_ENUMERATED:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		{
Packit Service 4684c1
		  len2 = -1;
Packit Service 4684c1
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
Packit Service 4684c1
		  fprintf (out, "  value:0x");
Packit Service 4684c1
		  if (len > 0)
Packit Service 4684c1
		    for (k = 0; k < len; k++)
Packit Service 4684c1
		      fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
Packit Service 4684c1
		}
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_BOOLEAN:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		{
Packit Service 4684c1
		  if (p->value[0] == 'T')
Packit Service 4684c1
		    fprintf (out, "  value:TRUE");
Packit Service 4684c1
		  else if (p->value[0] == 'F')
Packit Service 4684c1
		    fprintf (out, "  value:FALSE");
Packit Service 4684c1
		}
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_BIT_STRING:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		{
Packit Service 4684c1
		  len2 = -1;
Packit Service 4684c1
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
Packit Service 4684c1
		  if (len > 0)
Packit Service 4684c1
		    {
Packit Service 4684c1
		      fprintf (out, "  value(%i):",
Packit Service 4684c1
			       (len - 1) * 8 - (p->value[len2]));
Packit Service 4684c1
		      for (k = 1; k < len; k++)
Packit Service 4684c1
			fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
Packit Service 4684c1
		    }
Packit Service 4684c1
		}
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_GENERALIZED_TIME:
Packit Service 4684c1
	    case ASN1_ETYPE_UTC_TIME:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		{
Packit Service 4684c1
		  fprintf (out, "  value:");
Packit Service 4684c1
		  for (k = 0; k < p->value_len; k++)
Packit Service 4684c1
		    fprintf (out, "%c", (p->value)[k]);
Packit Service 4684c1
		}
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_GENERALSTRING:
Packit Service 4684c1
	    case ASN1_ETYPE_NUMERIC_STRING:
Packit Service 4684c1
	    case ASN1_ETYPE_IA5_STRING:
Packit Service 4684c1
	    case ASN1_ETYPE_TELETEX_STRING:
Packit Service 4684c1
	    case ASN1_ETYPE_PRINTABLE_STRING:
Packit Service 4684c1
	    case ASN1_ETYPE_UNIVERSAL_STRING:
Packit Service 4684c1
	    case ASN1_ETYPE_UTF8_STRING:
Packit Service 4684c1
	    case ASN1_ETYPE_VISIBLE_STRING:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		{
Packit Service 4684c1
		  len2 = -1;
Packit Service 4684c1
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
Packit Service 4684c1
		  fprintf (out, "  value:");
Packit Service 4684c1
		  if (len > 0)
Packit Service 4684c1
		    for (k = 0; k < len; k++)
Packit Service 4684c1
		      fprintf (out, "%c", (p->value)[k + len2]);
Packit Service 4684c1
		}
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_BMP_STRING:
Packit Service 4684c1
	    case ASN1_ETYPE_OCTET_STRING:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		{
Packit Service 4684c1
		  len2 = -1;
Packit Service 4684c1
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
Packit Service 4684c1
		  fprintf (out, "  value:");
Packit Service 4684c1
		  if (len > 0)
Packit Service 4684c1
		    for (k = 0; k < len; k++)
Packit Service 4684c1
		      fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
Packit Service 4684c1
		}
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_OBJECT_ID:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		fprintf (out, "  value:%s", p->value);
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_ANY:
Packit Service 4684c1
	      if (p->value)
Packit Service 4684c1
		{
Packit Service 4684c1
		  len3 = -1;
Packit Service 4684c1
		  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
Packit Service 4684c1
		  fprintf (out, "  value:");
Packit Service 4684c1
		  if (len2 > 0)
Packit Service 4684c1
		    for (k = 0; k < len2; k++)
Packit Service 4684c1
		      fprintf (out, "%02x", (unsigned) (p->value)[k + len3]);
Packit Service 4684c1
		}
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    case ASN1_ETYPE_SET:
Packit Service 4684c1
	    case ASN1_ETYPE_SET_OF:
Packit Service 4684c1
	    case ASN1_ETYPE_CHOICE:
Packit Service 4684c1
	    case ASN1_ETYPE_DEFINITIONS:
Packit Service 4684c1
	    case ASN1_ETYPE_SEQUENCE_OF:
Packit Service 4684c1
	    case ASN1_ETYPE_SEQUENCE:
Packit Service 4684c1
	    case ASN1_ETYPE_NULL:
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    default:
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
	{
Packit Service 4684c1
	  if (p->type & 0x1FFFFF00)
Packit Service 4684c1
	    {
Packit Service 4684c1
	      fprintf (out, "  attr:");
Packit Service 4684c1
	      if (p->type & CONST_UNIVERSAL)
Packit Service 4684c1
		fprintf (out, "UNIVERSAL,");
Packit Service 4684c1
	      if (p->type & CONST_PRIVATE)
Packit Service 4684c1
		fprintf (out, "PRIVATE,");
Packit Service 4684c1
	      if (p->type & CONST_APPLICATION)
Packit Service 4684c1
		fprintf (out, "APPLICATION,");
Packit Service 4684c1
	      if (p->type & CONST_EXPLICIT)
Packit Service 4684c1
		fprintf (out, "EXPLICIT,");
Packit Service 4684c1
	      if (p->type & CONST_IMPLICIT)
Packit Service 4684c1
		fprintf (out, "IMPLICIT,");
Packit Service 4684c1
	      if (p->type & CONST_TAG)
Packit Service 4684c1
		fprintf (out, "TAG,");
Packit Service 4684c1
	      if (p->type & CONST_DEFAULT)
Packit Service 4684c1
		fprintf (out, "DEFAULT,");
Packit Service 4684c1
	      if (p->type & CONST_TRUE)
Packit Service 4684c1
		fprintf (out, "TRUE,");
Packit Service 4684c1
	      if (p->type & CONST_FALSE)
Packit Service 4684c1
		fprintf (out, "FALSE,");
Packit Service 4684c1
	      if (p->type & CONST_LIST)
Packit Service 4684c1
		fprintf (out, "LIST,");
Packit Service 4684c1
	      if (p->type & CONST_MIN_MAX)
Packit Service 4684c1
		fprintf (out, "MIN_MAX,");
Packit Service 4684c1
	      if (p->type & CONST_OPTION)
Packit Service 4684c1
		fprintf (out, "OPTION,");
Packit Service 4684c1
	      if (p->type & CONST_1_PARAM)
Packit Service 4684c1
		fprintf (out, "1_PARAM,");
Packit Service 4684c1
	      if (p->type & CONST_SIZE)
Packit Service 4684c1
		fprintf (out, "SIZE,");
Packit Service 4684c1
	      if (p->type & CONST_DEFINED_BY)
Packit Service 4684c1
		fprintf (out, "DEF_BY,");
Packit Service 4684c1
	      if (p->type & CONST_GENERALIZED)
Packit Service 4684c1
		fprintf (out, "GENERALIZED,");
Packit Service 4684c1
	      if (p->type & CONST_UTC)
Packit Service 4684c1
		fprintf (out, "UTC,");
Packit Service 4684c1
	      if (p->type & CONST_SET)
Packit Service 4684c1
		fprintf (out, "SET,");
Packit Service 4684c1
	      if (p->type & CONST_NOT_USED)
Packit Service 4684c1
		fprintf (out, "NOT_USED,");
Packit Service 4684c1
	      if (p->type & CONST_ASSIGN)
Packit Service 4684c1
		fprintf (out, "ASSIGNMENT,");
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (mode == ASN1_PRINT_ALL)
Packit Service 4684c1
	{
Packit Service 4684c1
	  fprintf (out, "\n");
Packit Service 4684c1
	}
Packit Service 4684c1
      else
Packit Service 4684c1
	{
Packit Service 4684c1
	  switch (type_field (p->type))
Packit Service 4684c1
	    {
Packit Service 4684c1
	    case ASN1_ETYPE_CONSTANT:
Packit Service 4684c1
	    case ASN1_ETYPE_TAG:
Packit Service 4684c1
	    case ASN1_ETYPE_SIZE:
Packit Service 4684c1
	      break;
Packit Service 4684c1
	    default:
Packit Service 4684c1
	      fprintf (out, "\n");
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
      if (p->down)
Packit Service 4684c1
	{
Packit Service 4684c1
	  p = p->down;
Packit Service 4684c1
	  indent += 2;
Packit Service 4684c1
	}
Packit Service 4684c1
      else if (p == root)
Packit Service 4684c1
	{
Packit Service 4684c1
	  p = NULL;
Packit Service 4684c1
	  break;
Packit Service 4684c1
	}
Packit Service 4684c1
      else if (p->right)
Packit Service 4684c1
	p = p->right;
Packit Service 4684c1
      else
Packit Service 4684c1
	{
Packit Service 4684c1
	  while (1)
Packit Service 4684c1
	    {
Packit Service 4684c1
	      p = _asn1_find_up (p);
Packit Service 4684c1
	      if (p == root)
Packit Service 4684c1
		{
Packit Service 4684c1
		  p = NULL;
Packit Service 4684c1
		  break;
Packit Service 4684c1
		}
Packit Service 4684c1
	      indent -= 2;
Packit Service 4684c1
	      if (p->right)
Packit Service 4684c1
		{
Packit Service 4684c1
		  p = p->right;
Packit Service 4684c1
		  break;
Packit Service 4684c1
		}
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
    }
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_number_of_elements:
Packit Service 4684c1
 * @element: pointer to the root of an ASN1 structure.
Packit Service 4684c1
 * @name: the name of a sub-structure of ROOT.
Packit Service 4684c1
 * @num: pointer to an integer where the result will be stored
Packit Service 4684c1
 *
Packit Service 4684c1
 * Counts the number of elements of a sub-structure called NAME with
Packit Service 4684c1
 * names equal to "?1","?2", ...
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
Packit Service 4684c1
 *   @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
asn1_number_of_elements (asn1_node_const element, const char *name, int *num)
Packit Service 4684c1
{
Packit Service 4684c1
  asn1_node_const node, p;
Packit Service 4684c1
Packit Service 4684c1
  if (num == NULL)
Packit Service 4684c1
    return ASN1_GENERIC_ERROR;
Packit Service 4684c1
Packit Service 4684c1
  *num = 0;
Packit Service 4684c1
Packit Service 4684c1
  node = asn1_find_node (element, name);
Packit Service 4684c1
  if (node == NULL)
Packit Service 4684c1
    return ASN1_ELEMENT_NOT_FOUND;
Packit Service 4684c1
Packit Service 4684c1
  p = node->down;
Packit Service 4684c1
Packit Service 4684c1
  while (p)
Packit Service 4684c1
    {
Packit Service 4684c1
      if (p->name[0] == '?')
Packit Service 4684c1
	(*num)++;
Packit Service 4684c1
      p = p->right;
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  return ASN1_SUCCESS;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_find_structure_from_oid:
Packit Service 4684c1
 * @definitions: ASN1 definitions
Packit Service 4684c1
 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
Packit Service 4684c1
 *
Packit Service 4684c1
 * Search the structure that is defined just after an OID definition.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %NULL when @oidValue not found, otherwise the pointer to a
Packit Service 4684c1
 *   constant string that contains the element name defined just after
Packit Service 4684c1
 *   the OID.
Packit Service 4684c1
 **/
Packit Service 4684c1
const char *
Packit Service 4684c1
asn1_find_structure_from_oid (asn1_node_const definitions, const char *oidValue)
Packit Service 4684c1
{
Packit Service 4684c1
  char name[2 * ASN1_MAX_NAME_SIZE + 2];
Packit Service 4684c1
  char value[ASN1_MAX_NAME_SIZE];
Packit Service 4684c1
  asn1_node p;
Packit Service 4684c1
  int len;
Packit Service 4684c1
  int result;
Packit Service 4684c1
  const char *definitionsName;
Packit Service 4684c1
Packit Service 4684c1
  if ((definitions == NULL) || (oidValue == NULL))
Packit Service 4684c1
    return NULL;		/* ASN1_ELEMENT_NOT_FOUND; */
Packit Service 4684c1
Packit Service 4684c1
  definitionsName = definitions->name;
Packit Service 4684c1
Packit Service 4684c1
  /* search the OBJECT_ID into definitions */
Packit Service 4684c1
  p = definitions->down;
Packit Service 4684c1
  while (p)
Packit Service 4684c1
    {
Packit Service 4684c1
      if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
Packit Service 4684c1
	  (p->type & CONST_ASSIGN))
Packit Service 4684c1
	{
Packit Service 4684c1
          snprintf(name, sizeof(name), "%s.%s", definitionsName, p->name);
Packit Service 4684c1
Packit Service 4684c1
	  len = ASN1_MAX_NAME_SIZE;
Packit Service 4684c1
	  result = asn1_read_value (definitions, name, value, &len;;
Packit Service 4684c1
Packit Service 4684c1
	  if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
Packit Service 4684c1
	    {
Packit Service 4684c1
	      p = p->right;
Packit Service 4684c1
	      if (p == NULL)	/* reach the end of ASN1 definitions */
Packit Service 4684c1
		return NULL;	/* ASN1_ELEMENT_NOT_FOUND; */
Packit Service 4684c1
Packit Service 4684c1
	      return p->name;
Packit Service 4684c1
	    }
Packit Service 4684c1
	}
Packit Service 4684c1
      p = p->right;
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  return NULL;			/* ASN1_ELEMENT_NOT_FOUND; */
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_copy_node:
Packit Service 4684c1
 * @dst: Destination asn1 node.
Packit Service 4684c1
 * @dst_name: Field name in destination node.
Packit Service 4684c1
 * @src: Source asn1 node.
Packit Service 4684c1
 * @src_name: Field name in source node.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Create a deep copy of a asn1_node variable. That
Packit Service 4684c1
 * function requires @dst to be expanded using asn1_create_element().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: Return %ASN1_SUCCESS on success.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
asn1_copy_node (asn1_node dst, const char *dst_name,
Packit Service 4684c1
		asn1_node_const src, const char *src_name)
Packit Service 4684c1
{
Packit Service 4684c1
  int result;
Packit Service 4684c1
  asn1_node dst_node;
Packit Service 4684c1
  void *data = NULL;
Packit Service 4684c1
  int size = 0;
Packit Service 4684c1
Packit Service 4684c1
  result = asn1_der_coding (src, src_name, NULL, &size, NULL);
Packit Service 4684c1
  if (result != ASN1_MEM_ERROR)
Packit Service 4684c1
    return result;
Packit Service 4684c1
Packit Service 4684c1
  data = malloc (size);
Packit Service 4684c1
  if (data == NULL)
Packit Service 4684c1
    return ASN1_MEM_ERROR;
Packit Service 4684c1
Packit Service 4684c1
  result = asn1_der_coding (src, src_name, data, &size, NULL);
Packit Service 4684c1
  if (result != ASN1_SUCCESS)
Packit Service 4684c1
    {
Packit Service 4684c1
      free (data);
Packit Service 4684c1
      return result;
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  dst_node = asn1_find_node (dst, dst_name);
Packit Service 4684c1
  if (dst_node == NULL)
Packit Service 4684c1
    {
Packit Service 4684c1
      free (data);
Packit Service 4684c1
      return ASN1_ELEMENT_NOT_FOUND;
Packit Service 4684c1
    }
Packit Service 4684c1
Packit Service 4684c1
  result = asn1_der_decoding (&dst_node, data, size, NULL);
Packit Service 4684c1
Packit Service 4684c1
  free (data);
Packit Service 4684c1
Packit Service 4684c1
  return result;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * asn1_dup_node:
Packit Service 4684c1
 * @src: Source asn1 node.
Packit Service 4684c1
 * @src_name: Field name in source node.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Create a deep copy of a asn1_node variable. This function
Packit Service 4684c1
 * will return an exact copy of the provided structure.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: Return %NULL on failure.
Packit Service 4684c1
 **/
Packit Service 4684c1
asn1_node
Packit Service 4684c1
asn1_dup_node (asn1_node_const src, const char *src_name)
Packit Service 4684c1
{
Packit Service 4684c1
  return _asn1_copy_structure2(src, src_name);
Packit Service 4684c1
}