Cyclomatic Complexity report for GNU Libtasn1 3.3

Back to GNU Libtasn1 3.3 Homepage
GNU Libtasn1 3.3 Cyclomatic Complexity Report

Report generated at: Sun Mar 24 11:36:40 CET 2013

Summary

Total number of functions | 103
Number of low risk functions | 69
Number of moderate risk functions | 15
Number of high risk functions | 13
Number of untestable functions | 6

Details for all functions

| Cyclomatic Complexity | Risk Evaluation
| 0 - 10 | Simple module, without much risk
| 11 - 20 | More complex module, moderate risk
| 21 - 50 | Complex module, high risk
| greater than 50 | Untestable module, very high risk

| Function Name | Modified Cyclo | Number of Statements | Number of Lines | Source File
↓ | asn1_der_decoding_element | 138 | 401 | 776 | decoding.c
    int
    asn1_der_decoding_element (asn1_node * structure, const char *elementName,
    			   const void *ider, int len, char *errorDescription)
    {
      asn1_node node, p, p2, p3, nodeFound = NULL;
      char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
      int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
      int counter, len2, len3, len4, move, ris, tlen;
      unsigned char class;
      unsigned long tag;
      int indefinite, result;
      const unsigned char *der = ider;

      node = *structure;

      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      if (elementName == NULL)
        {
          result = ASN1_ELEMENT_NOT_FOUND;
          goto cleanup;
        }

      if (node->type & CONST_OPTION)
        {
          result = ASN1_GENERIC_ERROR;
          goto cleanup;
        }

      if ((*structure)->name[0] != 0)
        {				/* Has *structure got a name? */
          nameLen -= strlen ((*structure)->name);
          if (nameLen > 0)
    	strcpy (currentName, (*structure)->name);
          else
    	{
    	  result = ASN1_MEM_ERROR;
    	  goto cleanup;
    	}
          if (!(strcmp (currentName, elementName)))
    	{
    	  state = FOUND;
    	  nodeFound = *structure;
    	}
          else if (!memcmp (currentName, elementName, strlen (currentName)))
    	state = SAME_BRANCH;
          else
    	state = OTHER_BRANCH;
        }
      else
        {				/* *structure doesn't have a name? */
          currentName[0] = 0;
          if (elementName[0] == 0)
    	{
    	  state = FOUND;
    	  nodeFound = *structure;
    	}
          else
    	{
    	  state = SAME_BRANCH;
    	}
        }

      counter = 0;
      move = DOWN;
      p = node;
      while (1)
        {

          ris = ASN1_SUCCESS;

          if (move != UP)
    	{
    	  if (p->type & CONST_SET)
    	    {
    	      p2 = _asn1_find_up (p);
    	      len2 = _asn1_strtol (p2->value, NULL, 10);
    	      if (counter == len2)
    		{
    		  p = p2;
    		  move = UP;
    		  continue;
    		}
    	      else if (counter > len2)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}
    	      p2 = p2->down;
    	      while (p2)
    		{
    		  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
    		    {
    		      if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
    			ris =
    			  _asn1_extract_tag_der (p2, der + counter,
    						 len - counter, &len2);
    		      else
    			{
    			  p3 = p2->down;
    			  while (p3)
    			    {
    			      ris =
    				_asn1_extract_tag_der (p3, der + counter,
    						       len - counter, &len2);
    			      if (ris == ASN1_SUCCESS)
    				break;
    			      p3 = p3->right;
    			    }
    			}
    		      if (ris == ASN1_SUCCESS)
    			{
    			  p2->type &= ~CONST_NOT_USED;
    			  p = p2;
    			  break;
    			}
    		    }
    		  p2 = p2->right;
    		}
    	      if (p2 == NULL)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}
    	    }

    	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
    	    {
    	      p2 = _asn1_find_up (p);
    	      len2 = _asn1_strtol (p2->value, NULL, 10);
    	      if (counter == len2)
    		{
    		  if (p->right)
    		    {
    		      p2 = p->right;
    		      move = RIGHT;
    		    }
    		  else
    		    move = UP;

    		  if (p->type & CONST_OPTION)
    		    asn1_delete_structure (&p);

    		  p = p2;
    		  continue;
    		}
    	    }

    	  if (type_field (p->type) == ASN1_ETYPE_CHOICE)
    	    {
    	      while (p->down)
    		{
    		  if (counter < len)
    		    ris =
    		      _asn1_extract_tag_der (p->down, der + counter,
    					     len - counter, &len2);
    		  else
    		    ris = ASN1_DER_ERROR;
    		  if (ris == ASN1_SUCCESS)
    		    {
    		      while (p->down->right)
    			{
    			  p2 = p->down->right;
    			  asn1_delete_structure (&p2);
    			}
    		      break;
    		    }
    		  else if (ris == ASN1_ERROR_TYPE_ANY)
    		    {
    		      result = ASN1_ERROR_TYPE_ANY;
    		      goto cleanup;
    		    }
    		  else
    		    {
    		      p2 = p->down;
    		      asn1_delete_structure (&p2);
    		    }
    		}

    	      if (p->down == NULL)
    		{
    		  if (!(p->type & CONST_OPTION))
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }
    		}
    	      else
    		p = p->down;
    	    }

    	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
    	    {
    	      p2 = _asn1_find_up (p);
    	      len2 = _asn1_strtol (p2->value, NULL, 10);
    	      if (counter > len2)
    		ris = ASN1_TAG_ERROR;
    	    }

    	  if (ris == ASN1_SUCCESS)
    	    ris =
    	      _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
    	  if (ris != ASN1_SUCCESS)
    	    {
    	      if (p->type & CONST_OPTION)
    		{
    		  p->type |= CONST_NOT_USED;
    		  move = RIGHT;
    		}
    	      else if (p->type & CONST_DEFAULT)
    		{
    		  _asn1_set_value (p, NULL, 0);
    		  move = RIGHT;
    		}
    	      else
    		{
    		  if (errorDescription != NULL)
    		    _asn1_error_description_tag_error (p, errorDescription);

    		  result = ASN1_TAG_ERROR;
    		  goto cleanup;
    		}
    	    }
    	  else
    	    counter += len2;
    	}

          if (ris == ASN1_SUCCESS)
    	{
    	  switch (type_field (p->type))
    	    {
    	    case ASN1_ETYPE_NULL:
    	      if (der[counter])
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      if (p == nodeFound)
    		state = EXIT;

    	      counter++;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_BOOLEAN:
    	      if (der[counter++] != 1)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      if (state == FOUND)
    		{
    		  if (der[counter++] == 0)
    		    _asn1_set_value (p, "F", 1);
    		  else
    		    _asn1_set_value (p, "T", 1);

    		  if (p == nodeFound)
    		    state = EXIT;

    		}
    	      else
    		counter++;

    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_INTEGER:
    	    case ASN1_ETYPE_ENUMERATED:
    	      len2 =
    		asn1_get_length_der (der + counter, len - counter, &len3);
    	      if (len2 < 0)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      if (state == FOUND)
    		{
    		  if (len3 + len2 > len - counter)
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }
    		  _asn1_set_value (p, der + counter, len3 + len2);

    		  if (p == nodeFound)
    		    state = EXIT;
    		}
    	      counter += len3 + len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_OBJECT_ID:
    	      if (state == FOUND)
    		{
    		  result =
    		    _asn1_get_objectid_der (der + counter, len - counter,
    					    &len2, temp, sizeof (temp));
    		  if (result != ASN1_SUCCESS)
    		    goto cleanup;

    		  tlen = strlen (temp);

    		  if (tlen > 0)
    		    _asn1_set_value (p, temp, tlen + 1);

    		  if (p == nodeFound)
    		    state = EXIT;
    		}
    	      else
    		{
    		  len2 =
    		    asn1_get_length_der (der + counter, len - counter, &len3);
    		  if (len2 < 0)
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }
    		  len2 += len3;
    		}

    	      counter += len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_GENERALIZED_TIME:
    	    case ASN1_ETYPE_UTC_TIME:
    	      if (state == FOUND)
    		{
    		  result =
    		    _asn1_get_time_der (der + counter, len - counter, &len2,
    					temp, sizeof (temp) - 1);
    		  if (result != ASN1_SUCCESS)
    		    goto cleanup;

    		  tlen = strlen (temp);
    		  if (tlen > 0)
    		    _asn1_set_value (p, temp, tlen + 1);

    		  if (p == nodeFound)
    		    state = EXIT;
    		}
    	      else
    		{
    		  len2 =
    		    asn1_get_length_der (der + counter, len - counter, &len3);
    		  if (len2 < 0)
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }
    		  len2 += len3;
    		}

    	      counter += len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_OCTET_STRING:
    	      len3 = len - counter;
    	      if (state == FOUND)
    		{
    		  result = _asn1_get_octet_string (der + counter, p, &len3);
    		  if (p == nodeFound)
    		    state = EXIT;
    		}
    	      else
    		result = _asn1_get_octet_string (der + counter, NULL, &len3);

    	      if (result != ASN1_SUCCESS)
    		goto cleanup;

    	      counter += len3;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_GENERALSTRING:
    	    case ASN1_ETYPE_NUMERIC_STRING:
    	    case ASN1_ETYPE_IA5_STRING:
    	    case ASN1_ETYPE_TELETEX_STRING:
    	    case ASN1_ETYPE_PRINTABLE_STRING:
    	    case ASN1_ETYPE_UNIVERSAL_STRING:
    	    case ASN1_ETYPE_BMP_STRING:
    	    case ASN1_ETYPE_UTF8_STRING:
    	    case ASN1_ETYPE_VISIBLE_STRING:
    	    case ASN1_ETYPE_BIT_STRING:
    	      len2 =
    		asn1_get_length_der (der + counter, len - counter, &len3);
    	      if (len2 < 0)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      if (state == FOUND)
    		{
    		  if (len3 + len2 > len - counter)
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }
    		  _asn1_set_value (p, der + counter, len3 + len2);

    		  if (p == nodeFound)
    		    state = EXIT;
    		}
    	      counter += len3 + len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_SEQUENCE:
    	    case ASN1_ETYPE_SET:
    	      if (move == UP)
    		{
    		  len2 = _asn1_strtol (p->value, NULL, 10);
    		  _asn1_set_value (p, NULL, 0);
    		  if (len2 == -1)
    		    {		/* indefinite length method */
    		      if ((der[counter]) || der[counter + 1])
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		      counter += 2;
    		    }
    		  else
    		    {		/* definite length method */
    		      if (len2 != counter)
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		    }
    		  if (p == nodeFound)
    		    state = EXIT;
    		  move = RIGHT;
    		}
    	      else
    		{		/* move==DOWN || move==RIGHT */
    		  if (state == OTHER_BRANCH)
    		    {
    		      len3 =
    			asn1_get_length_der (der + counter, len - counter,
    					     &len2);
    		      if (len3 < 0)
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		      counter += len2 + len3;
    		      move = RIGHT;
    		    }
    		  else
    		    {		/*  state==SAME_BRANCH or state==FOUND */
    		      len3 =
    			asn1_get_length_der (der + counter, len - counter,
    					     &len2);
    		      if (len3 < 0)
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		      counter += len2;
    		      if (len3 > 0)
    			{
    			  _asn1_ltostr (counter + len3, temp);
    			  tlen = strlen (temp);

    			  if (tlen > 0)
    			    _asn1_set_value (p, temp, tlen + 1);
    			  move = DOWN;
    			}
    		      else if (len3 == 0)
    			{
    			  p2 = p->down;
    			  while (p2)
    			    {
    			      if (type_field (p2->type) != ASN1_ETYPE_TAG)
    				{
    				  p3 = p2->right;
    				  asn1_delete_structure (&p2);
    				  p2 = p3;
    				}
    			      else
    				p2 = p2->right;
    			    }
    			  move = RIGHT;
    			}
    		      else
    			{	/* indefinite length method */
    			  _asn1_set_value (p, "-1", 3);
    			  move = DOWN;
    			}
    		    }
    		}
    	      break;
    	    case ASN1_ETYPE_SEQUENCE_OF:
    	    case ASN1_ETYPE_SET_OF:
    	      if (move == UP)
    		{
    		  len2 = _asn1_strtol (p->value, NULL, 10);
    		  if (len2 > counter)
    		    {
    		      _asn1_append_sequence_set (p);
    		      p = p->down;
    		      while (p->right)
    			p = p->right;
    		      move = RIGHT;
    		      continue;
    		    }
    		  _asn1_set_value (p, NULL, 0);
    		  if (len2 != counter)
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }

    		  if (p == nodeFound)
    		    state = EXIT;
    		}
    	      else
    		{		/* move==DOWN || move==RIGHT */
    		  if (state == OTHER_BRANCH)
    		    {
    		      len3 =
    			asn1_get_length_der (der + counter, len - counter,
    					     &len2);
    		      if (len3 < 0)
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		      counter += len2 + len3;
    		      move = RIGHT;
    		    }
    		  else
    		    {		/* state==FOUND or state==SAME_BRANCH */
    		      len3 =
    			asn1_get_length_der (der + counter, len - counter,
    					     &len2);
    		      if (len3 < 0)
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		      counter += len2;
    		      if (len3)
    			{
    			  _asn1_ltostr (counter + len3, temp);
    			  tlen = strlen (temp);

    			  if (tlen > 0)
    			    _asn1_set_value (p, temp, tlen + 1);
    			  p2 = p->down;
    			  while ((type_field (p2->type) == ASN1_ETYPE_TAG)
    				 || (type_field (p2->type) ==
    				     ASN1_ETYPE_SIZE))
    			    p2 = p2->right;
    			  if (p2->right == NULL)
    			    _asn1_append_sequence_set (p);
    			  p = p2;
    			  state = FOUND;
    			}
    		    }
    		}

    	      break;
    	    case ASN1_ETYPE_ANY:
    	      if (asn1_get_tag_der
    		  (der + counter, len - counter, &class, &len2,
    		   &tag) != ASN1_SUCCESS)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      if (counter + len2 > len)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      len4 =
    		asn1_get_length_der (der + counter + len2,
    				     len - counter - len2, &len3);
    	      if (len4 < -1)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      if (len4 != -1)
    		{
    		  len2 += len4;
    		  if (state == FOUND)
    		    {
    		      _asn1_set_value_lv (p, der + counter, len2 + len3);

    		      if (p == nodeFound)
    			state = EXIT;
    		    }
    		  counter += len2 + len3;
    		}
    	      else
    		{		/* indefinite length */
    		  /* Check indefinite lenth method in an EXPLICIT TAG */
    		  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
    		    indefinite = 1;
    		  else
    		    indefinite = 0;

    		  len2 = len - counter;
    		  result =
    		    _asn1_get_indefinite_length_string (der + counter, &len2);
    		  if (result != ASN1_SUCCESS)
    		    goto cleanup;

    		  if (state == FOUND)
    		    {
    		      _asn1_set_value_lv (p, der + counter, len2);

    		      if (p == nodeFound)
    			state = EXIT;
    		    }

    		  counter += len2;

    		  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
    		     an indefinite length method. */
    		  if (indefinite)
    		    {
    		      if (!der[counter] && !der[counter + 1])
    			{
    			  counter += 2;
    			}
    		      else
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		    }
    		}
    	      move = RIGHT;
    	      break;

    	    default:
    	      move = (move == UP) ? RIGHT : DOWN;
    	      break;
    	    }
    	}

          if ((p == node && move != DOWN) || (state == EXIT))
    	break;

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

    	      if (state != FOUND)
    		{
    		  nameLen -= strlen (p->name) + 1;
    		  if (nameLen > 0)
    		    {
    		      if (currentName[0])
    			strcat (currentName, ".");
    		      strcat (currentName, p->name);
    		    }
    		  else
    		    {
    		      result = ASN1_MEM_ERROR;
    		      goto cleanup;
    		    }
    		  if (!(strcmp (currentName, elementName)))
    		    {
    		      state = FOUND;
    		      nodeFound = p;
    		    }
    		  else
    		    if (!memcmp
    			(currentName, elementName, strlen (currentName)))
    		    state = SAME_BRANCH;
    		  else
    		    state = OTHER_BRANCH;
    		}
    	    }
    	  else
    	    move = RIGHT;
    	}

          if ((move == RIGHT) && !(p->type & CONST_SET))
    	{
    	  if (p->right)
    	    {
    	      p = p->right;

    	      if (state != FOUND)
    		{
    		  dot_p = char_p = currentName;
    		  while ((char_p = strchr (char_p, '.')))
    		    {
    		      dot_p = char_p++;
    		      dot_p++;
    		    }

    		  nameLen += strlen (currentName) - (dot_p - currentName);
    		  *dot_p = 0;

    		  nameLen -= strlen (p->name);
    		  if (nameLen > 0)
    		    strcat (currentName, p->name);
    		  else
    		    {
    		      result = ASN1_MEM_ERROR;
    		      goto cleanup;
    		    }

    		  if (!(strcmp (currentName, elementName)))
    		    {
    		      state = FOUND;
    		      nodeFound = p;
    		    }
    		  else
    		    if (!memcmp
    			(currentName, elementName, strlen (currentName)))
    		    state = SAME_BRANCH;
    		  else
    		    state = OTHER_BRANCH;
    		}
    	    }
    	  else
    	    move = UP;
    	}

          if (move == UP)
    	{
    	  p = _asn1_find_up (p);

    	  if (state != FOUND)
    	    {
    	      dot_p = char_p = currentName;
    	      while ((char_p = strchr (char_p, '.')))
    		{
    		  dot_p = char_p++;
    		  dot_p++;
    		}

    	      nameLen += strlen (currentName) - (dot_p - currentName);
    	      *dot_p = 0;

    	      if (!(strcmp (currentName, elementName)))
    		{
    		  state = FOUND;
    		  nodeFound = p;
    		}
    	      else
    		if (!memcmp (currentName, elementName, strlen (currentName)))
    		state = SAME_BRANCH;
    	      else
    		state = OTHER_BRANCH;
    	    }
    	}
        }

      _asn1_delete_not_used (*structure);

      if (counter > len)
        {
          result = ASN1_DER_ERROR;
          goto cleanup;
        }

      return ASN1_SUCCESS;

    cleanup:
      asn1_delete_structure (structure);
      return result;
    }
↓ | asn1_der_decoding | 102 | 299 | 551 | decoding.c
    int
    asn1_der_decoding (asn1_node * element, const void *ider, int len,
    		   char *errorDescription)
    {
      asn1_node node, p, p2, p3;
      char temp[128];
      int counter, len2, len3, len4, move, ris, tlen;
      unsigned char class;
      unsigned long tag;
      int indefinite, result;
      const unsigned char *der = ider;

      node = *element;

      if (errorDescription != NULL)
        errorDescription[0] = 0;

      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      if (node->type & CONST_OPTION)
        {
          result = ASN1_GENERIC_ERROR;
          goto cleanup;
        }

      counter = 0;
      move = DOWN;
      p = node;
      while (1)
        {
          ris = ASN1_SUCCESS;
          if (move != UP)
    	{
    	  if (p->type & CONST_SET)
    	    {
    	      p2 = _asn1_find_up (p);
    	      len2 = _asn1_strtol (p2->value, NULL, 10);
    	      if (len2 == -1)
    		{
    		  if (!der[counter] && !der[counter + 1])
    		    {
    		      p = p2;
    		      move = UP;
    		      counter += 2;
    		      continue;
    		    }
    		}
    	      else if (counter == len2)
    		{
    		  p = p2;
    		  move = UP;
    		  continue;
    		}
    	      else if (counter > len2)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}
    	      p2 = p2->down;
    	      while (p2)
    		{
    		  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
    		    {
    		      if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
    			ris =
    			  _asn1_extract_tag_der (p2, der + counter,
    						 len - counter, &len2);
    		      else
    			{
    			  p3 = p2->down;
    			  while (p3)
    			    {
    			      ris =
    				_asn1_extract_tag_der (p3, der + counter,
    						       len - counter, &len2);
    			      if (ris == ASN1_SUCCESS)
    				break;
    			      p3 = p3->right;
    			    }
    			}
    		      if (ris == ASN1_SUCCESS)
    			{
    			  p2->type &= ~CONST_NOT_USED;
    			  p = p2;
    			  break;
    			}
    		    }
    		  p2 = p2->right;
    		}
    	      if (p2 == NULL)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}
    	    }

    	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
    	    {
    	      p2 = _asn1_find_up (p);
    	      len2 = _asn1_strtol (p2->value, NULL, 10);
    	      if (counter == len2)
    		{
    		  if (p->right)
    		    {
    		      p2 = p->right;
    		      move = RIGHT;
    		    }
    		  else
    		    move = UP;

    		  if (p->type & CONST_OPTION)
    		    asn1_delete_structure (&p);

    		  p = p2;
    		  continue;
    		}
    	    }

    	  if (type_field (p->type) == ASN1_ETYPE_CHOICE)
    	    {
    	      while (p->down)
    		{
    		  if (counter < len)
    		    ris =
    		      _asn1_extract_tag_der (p->down, der + counter,
    					     len - counter, &len2);
    		  else
    		    ris = ASN1_DER_ERROR;
    		  if (ris == ASN1_SUCCESS)
    		    {
    		      while (p->down->right)
    			{
    			  p2 = p->down->right;
    			  asn1_delete_structure (&p2);
    			}
    		      break;
    		    }
    		  else if (ris == ASN1_ERROR_TYPE_ANY)
    		    {
    		      result = ASN1_ERROR_TYPE_ANY;
    		      goto cleanup;
    		    }
    		  else
    		    {
    		      p2 = p->down;
    		      asn1_delete_structure (&p2);
    		    }
    		}

    	      if (p->down == NULL)
    		{
    		  if (!(p->type & CONST_OPTION))
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }
    		}
    	      else
    		p = p->down;
    	    }

    	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
    	    {
    	      p2 = _asn1_find_up (p);
    	      len2 = _asn1_strtol (p2->value, NULL, 10);
    	      if ((len2 != -1) && (counter > len2))
    		ris = ASN1_TAG_ERROR;
    	    }

    	  if (ris == ASN1_SUCCESS)
    	    ris =
    	      _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
    	  if (ris != ASN1_SUCCESS)
    	    {
    	      if (p->type & CONST_OPTION)
    		{
    		  p->type |= CONST_NOT_USED;
    		  move = RIGHT;
    		}
    	      else if (p->type & CONST_DEFAULT)
    		{
    		  _asn1_set_value (p, NULL, 0);
    		  move = RIGHT;
    		}
    	      else
    		{
    		  if (errorDescription != NULL)
    		    _asn1_error_description_tag_error (p, errorDescription);

    		  result = ASN1_TAG_ERROR;
    		  goto cleanup;
    		}
    	    }
    	  else
    	    counter += len2;
    	}

          if (ris == ASN1_SUCCESS)
    	{
    	  switch (type_field (p->type))
    	    {
    	    case ASN1_ETYPE_NULL:
    	      if (der[counter])
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}
    	      counter++;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_BOOLEAN:
    	      if (der[counter++] != 1)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}
    	      if (der[counter++] == 0)
    		_asn1_set_value (p, "F", 1);
    	      else
    		_asn1_set_value (p, "T", 1);
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_INTEGER:
    	    case ASN1_ETYPE_ENUMERATED:
    	      len2 =
    		asn1_get_length_der (der + counter, len - counter, &len3);
    	      if (len2 < 0)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      _asn1_set_value (p, der + counter, len3 + len2);
    	      counter += len3 + len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_OBJECT_ID:
    	      result =
    		_asn1_get_objectid_der (der + counter, len - counter, &len2,
    					temp, sizeof (temp));
    	      if (result != ASN1_SUCCESS)
    		goto cleanup;

    	      tlen = strlen (temp);
    	      if (tlen > 0)
    		_asn1_set_value (p, temp, tlen + 1);
    	      counter += len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_GENERALIZED_TIME:
    	    case ASN1_ETYPE_UTC_TIME:
    	      result =
    		_asn1_get_time_der (der + counter, len - counter, &len2, temp,
    				    sizeof (temp) - 1);
    	      if (result != ASN1_SUCCESS)
    		goto cleanup;

    	      tlen = strlen (temp);
    	      if (tlen > 0)
    		_asn1_set_value (p, temp, tlen);
    	      counter += len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_OCTET_STRING:
    	      len3 = len - counter;
    	      result = _asn1_get_octet_string (der + counter, p, &len3);
    	      if (result != ASN1_SUCCESS)
    		goto cleanup;

    	      counter += len3;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_GENERALSTRING:
    	    case ASN1_ETYPE_NUMERIC_STRING:
    	    case ASN1_ETYPE_IA5_STRING:
    	    case ASN1_ETYPE_TELETEX_STRING:
    	    case ASN1_ETYPE_PRINTABLE_STRING:
    	    case ASN1_ETYPE_UNIVERSAL_STRING:
    	    case ASN1_ETYPE_BMP_STRING:
    	    case ASN1_ETYPE_UTF8_STRING:
    	    case ASN1_ETYPE_VISIBLE_STRING:
    	    case ASN1_ETYPE_BIT_STRING:
    	      len2 =
    		asn1_get_length_der (der + counter, len - counter, &len3);
    	      if (len2 < 0)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      _asn1_set_value (p, der + counter, len3 + len2);
    	      counter += len3 + len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_SEQUENCE:
    	    case ASN1_ETYPE_SET:
    	      if (move == UP)
    		{
    		  len2 = _asn1_strtol (p->value, NULL, 10);
    		  _asn1_set_value (p, NULL, 0);
    		  if (len2 == -1)
    		    {		/* indefinite length method */
    		      if (len - counter + 1 > 0)
    			{
    			  if ((der[counter]) || der[counter + 1])
    			    {
    			      result = ASN1_DER_ERROR;
    			      goto cleanup;
    			    }
    			}
    		      else
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		      counter += 2;
    		    }
    		  else
    		    {		/* definite length method */
    		      if (len2 != counter)
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		    }
    		  move = RIGHT;
    		}
    	      else
    		{		/* move==DOWN || move==RIGHT */
    		  len3 =
    		    asn1_get_length_der (der + counter, len - counter, &len2);
    		  if (len3 < -1)
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }
    		  counter += len2;
    		  if (len3 > 0)
    		    {
    		      _asn1_ltostr (counter + len3, temp);
    		      tlen = strlen (temp);
    		      if (tlen > 0)
    			_asn1_set_value (p, temp, tlen + 1);
    		      move = DOWN;
    		    }
    		  else if (len3 == 0)
    		    {
    		      p2 = p->down;
    		      while (p2)
    			{
    			  if (type_field (p2->type) != ASN1_ETYPE_TAG)
    			    {
    			      p3 = p2->right;
    			      asn1_delete_structure (&p2);
    			      p2 = p3;
    			    }
    			  else
    			    p2 = p2->right;
    			}
    		      move = RIGHT;
    		    }
    		  else
    		    {		/* indefinite length method */
    		      _asn1_set_value (p, "-1", 3);
    		      move = DOWN;
    		    }
    		}
    	      break;
    	    case ASN1_ETYPE_SEQUENCE_OF:
    	    case ASN1_ETYPE_SET_OF:
    	      if (move == UP)
    		{
    		  len2 = _asn1_strtol (p->value, NULL, 10);
    		  if (len2 == -1)
    		    {		/* indefinite length method */
    		      if ((counter + 2) > len)
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}

    		      if ((der[counter]) || der[counter + 1])
    			{
    			  _asn1_append_sequence_set (p);
    			  p = p->down;
    			  while (p->right)
    			    p = p->right;
    			  move = RIGHT;
    			  continue;
    			}
    		      _asn1_set_value (p, NULL, 0);
    		      counter += 2;
    		    }
    		  else
    		    {		/* definite length method */
    		      if (len2 > counter)
    			{
    			  _asn1_append_sequence_set (p);
    			  p = p->down;
    			  while (p->right)
    			    p = p->right;
    			  move = RIGHT;
    			  continue;
    			}
    		      _asn1_set_value (p, NULL, 0);
    		      if (len2 != counter)
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		    }
    		}
    	      else
    		{		/* move==DOWN || move==RIGHT */
    		  len3 =
    		    asn1_get_length_der (der + counter, len - counter, &len2);
    		  if (len3 < -1)
    		    {
    		      result = ASN1_DER_ERROR;
    		      goto cleanup;
    		    }
    		  counter += len2;
    		  if (len3)
    		    {
    		      if (len3 > 0)
    			{	/* definite length method */
    			  _asn1_ltostr (counter + len3, temp);
    			  tlen = strlen (temp);

    			  if (tlen > 0)
    			    _asn1_set_value (p, temp, tlen + 1);
    			}
    		      else
    			{	/* indefinite length method */
    			  _asn1_set_value (p, "-1", 3);
    			}
    		      p2 = p->down;
    		      while ((type_field (p2->type) == ASN1_ETYPE_TAG)
    			     || (type_field (p2->type) == ASN1_ETYPE_SIZE))
    			p2 = p2->right;
    		      if (p2->right == NULL)
    			_asn1_append_sequence_set (p);
    		      p = p2;
    		    }
    		}
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_ANY:
    	      if (asn1_get_tag_der
    		  (der + counter, len - counter, &class, &len2,
    		   &tag) != ASN1_SUCCESS)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}

    	      if (counter + len2 > len)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}
    	      len4 =
    		asn1_get_length_der (der + counter + len2,
    				     len - counter - len2, &len3);
    	      if (len4 < -1)
    		{
    		  result = ASN1_DER_ERROR;
    		  goto cleanup;
    		}
    	      if (len4 != -1)
    		{
    		  len2 += len4;
    		  _asn1_set_value_lv (p, der + counter, len2 + len3);
    		  counter += len2 + len3;
    		}
    	      else
    		{		/* indefinite length */
    		  /* Check indefinite lenth method in an EXPLICIT TAG */
    		  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
    		    indefinite = 1;
    		  else
    		    indefinite = 0;

    		  len2 = len - counter;
    		  result =
    		    _asn1_get_indefinite_length_string (der + counter, &len2);
    		  if (result != ASN1_SUCCESS)
    		    goto cleanup;

    		  _asn1_set_value_lv (p, der + counter, len2);
    		  counter += len2;

    		  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
    		     an indefinite length method. */
    		  if (indefinite)
    		    {
    		      if (!der[counter] && !der[counter + 1])
    			{
    			  counter += 2;
    			}
    		      else
    			{
    			  result = ASN1_DER_ERROR;
    			  goto cleanup;
    			}
    		    }
    		}
    	      move = RIGHT;
    	      break;
    	    default:
    	      move = (move == UP) ? RIGHT : DOWN;
    	      break;
    	    }
    	}

          if (p == node && move != DOWN)
    	break;

          if (move == DOWN)
    	{
    	  if (p->down)
    	    p = p->down;
    	  else
    	    move = RIGHT;
    	}
          if ((move == RIGHT) && !(p->type & CONST_SET))
    	{
    	  if (p->right)
    	    p = p->right;
    	  else
    	    move = UP;
    	}
          if (move == UP)
    	p = _asn1_find_up (p);
        }

      _asn1_delete_not_used (*element);

      if (counter != len)
        {
          result = ASN1_DER_ERROR;
          goto cleanup;
        }

      return ASN1_SUCCESS;

    cleanup:
      asn1_delete_structure (element);
      return result;
    }
↓ | asn1_write_value | 92 | 207 | 341 | element.c
    int
    asn1_write_value (asn1_node node_root, const char *name,
    		  const void *ivalue, int len)
    {
      asn1_node node, p, p2;
      unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
      int len2, k, k2, negative;
      size_t i;
      const unsigned char *value = ivalue;
      unsigned int type;

      node = asn1_find_node (node_root, name);
      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
        {
          asn1_delete_structure (&node);
          return ASN1_SUCCESS;
        }

      type = type_field (node->type);

      if ((type == ASN1_ETYPE_SEQUENCE_OF) && (value == NULL) && (len == 0))
        {
          p = node->down;
          while ((type_field (p->type) == ASN1_ETYPE_TAG)
    	     || (type_field (p->type) == ASN1_ETYPE_SIZE))
    	p = p->right;

          while (p->right)
    	asn1_delete_structure (&p->right);

          return ASN1_SUCCESS;
        }

      switch (type)
        {
        case ASN1_ETYPE_BOOLEAN:
          if (!_asn1_strcmp (value, "TRUE"))
    	{
    	  if (node->type & CONST_DEFAULT)
    	    {
    	      p = node->down;
    	      while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
    		p = p->right;
    	      if (p->type & CONST_TRUE)
    		_asn1_set_value (node, NULL, 0);
    	      else
    		_asn1_set_value (node, "T", 1);
    	    }
    	  else
    	    _asn1_set_value (node, "T", 1);
    	}
          else if (!_asn1_strcmp (value, "FALSE"))
    	{
    	  if (node->type & CONST_DEFAULT)
    	    {
    	      p = node->down;
    	      while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
    		p = p->right;
    	      if (p->type & CONST_FALSE)
    		_asn1_set_value (node, NULL, 0);
    	      else
    		_asn1_set_value (node, "F", 1);
    	    }
    	  else
    	    _asn1_set_value (node, "F", 1);
    	}
          else
    	return ASN1_VALUE_NOT_VALID;
          break;
        case ASN1_ETYPE_INTEGER:
        case ASN1_ETYPE_ENUMERATED:
          if (len == 0)
    	{
    	  if ((isdigit (value[0])) || (value[0] == '-'))
    	    {
    	      value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
    	      if (value_temp == NULL)
    		return ASN1_MEM_ALLOC_ERROR;

    	      _asn1_convert_integer (value, value_temp,
    				     SIZEOF_UNSIGNED_LONG_INT, &len);
    	    }
    	  else
    	    {			/* is an identifier like v1 */
    	      if (!(node->type & CONST_LIST))
    		return ASN1_VALUE_NOT_VALID;
    	      p = node->down;
    	      while (p)
    		{
    		  if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
    		    {
    		      if (!_asn1_strcmp (p->name, value))
    			{
    			  value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
    			  if (value_temp == NULL)
    			    return ASN1_MEM_ALLOC_ERROR;

    			  _asn1_convert_integer (p->value,
    						 value_temp,
    						 SIZEOF_UNSIGNED_LONG_INT,
    						 &len);
    			  break;
    			}
    		    }
    		  p = p->right;
    		}
    	      if (p == NULL)
    		return ASN1_VALUE_NOT_VALID;
    	    }
    	}
          else
    	{			/* len != 0 */
    	  value_temp = malloc (len);
    	  if (value_temp == NULL)
    	    return ASN1_MEM_ALLOC_ERROR;
    	  memcpy (value_temp, value, len);
    	}

          if (value_temp[0] & 0x80)
    	negative = 1;
          else
    	negative = 0;

          if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED))
    	{
    	  free (value_temp);
    	  return ASN1_VALUE_NOT_VALID;
    	}

          for (k = 0; k < len - 1; k++)
    	if (negative && (value_temp[k] != 0xFF))
    	  break;
    	else if (!negative && value_temp[k])
    	  break;

          if ((negative && !(value_temp[k] & 0x80)) ||
    	  (!negative && (value_temp[k] & 0x80)))
    	k--;

          _asn1_set_value_lv (node, value_temp + k, len - k);

          if (node->type & CONST_DEFAULT)
    	{
    	  p = node->down;
    	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
    	    p = p->right;
    	  if ((isdigit (p->value[0])) || (p->value[0] == '-'))
    	    {
    	      default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
    	      if (default_temp == NULL)
    		{
    		  free (value_temp);
    		  return ASN1_MEM_ALLOC_ERROR;
    		}

    	      _asn1_convert_integer (p->value, default_temp,
    				     SIZEOF_UNSIGNED_LONG_INT, &len2);
    	    }
    	  else
    	    {			/* is an identifier like v1 */
    	      if (!(node->type & CONST_LIST))
    		{
    		  free (value_temp);
    		  return ASN1_VALUE_NOT_VALID;
    		}
    	      p2 = node->down;
    	      while (p2)
    		{
    		  if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
    		    {
    		      if (!_asn1_strcmp (p2->name, p->value))
    			{
    			  default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
    			  if (default_temp == NULL)
    			    {
    			      free (value_temp);
    			      return ASN1_MEM_ALLOC_ERROR;
    			    }

    			  _asn1_convert_integer (p2->value,
    						 default_temp,
    						 SIZEOF_UNSIGNED_LONG_INT,
    						 &len2);
    			  break;
    			}
    		    }
    		  p2 = p2->right;
    		}
    	      if (p2 == NULL)
    		{
    		  free (value_temp);
    		  return ASN1_VALUE_NOT_VALID;
    		}
    	    }

    	  if ((len - k) == len2)
    	    {
    	      for (k2 = 0; k2 < len2; k2++)
    		if (value_temp[k + k2] != default_temp[k2])
    		  {
    		    break;
    		  }
    	      if (k2 == len2)
    		_asn1_set_value (node, NULL, 0);
    	    }
    	  free (default_temp);
    	}
          free (value_temp);
          break;
        case ASN1_ETYPE_OBJECT_ID:
          for (i = 0; i < _asn1_strlen (value); i++)
    	if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
    	  return ASN1_VALUE_NOT_VALID;
          if (node->type & CONST_DEFAULT)
    	{
    	  p = node->down;
    	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
    	    p = p->right;
    	  if (!_asn1_strcmp (value, p->value))
    	    {
    	      _asn1_set_value (node, NULL, 0);
    	      break;
    	    }
    	}
          _asn1_set_value (node, value, _asn1_strlen (value) + 1);
          break;
        case ASN1_ETYPE_UTC_TIME:
          {
    	len = _asn1_strlen (value);
    	if (len < 11)
    	  return ASN1_VALUE_NOT_VALID;
    	for (k = 0; k < 10; k++)
    	  if (!isdigit (value[k]))
    	    return ASN1_VALUE_NOT_VALID;
    	switch (len)
    	  {
    	  case 11:
    	    if (value[10] != 'Z')
    	      return ASN1_VALUE_NOT_VALID;
    	    break;
    	  case 13:
    	    if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
    		(value[12] != 'Z'))
    	      return ASN1_VALUE_NOT_VALID;
    	    break;
    	  case 15:
    	    if ((value[10] != '+') && (value[10] != '-'))
    	      return ASN1_VALUE_NOT_VALID;
    	    for (k = 11; k < 15; k++)
    	      if (!isdigit (value[k]))
    		return ASN1_VALUE_NOT_VALID;
    	    break;
    	  case 17:
    	    if ((!isdigit (value[10])) || (!isdigit (value[11])))
    	      return ASN1_VALUE_NOT_VALID;
    	    if ((value[12] != '+') && (value[12] != '-'))
    	      return ASN1_VALUE_NOT_VALID;
    	    for (k = 13; k < 17; k++)
    	      if (!isdigit (value[k]))
    		return ASN1_VALUE_NOT_VALID;
    	    break;
    	  default:
    	    return ASN1_VALUE_NOT_FOUND;
    	  }
    	_asn1_set_value (node, value, len);
          }
          break;
        case ASN1_ETYPE_GENERALIZED_TIME:
          len = _asn1_strlen (value);
          _asn1_set_value (node, value, len);
          break;
        case ASN1_ETYPE_OCTET_STRING:
        case ASN1_ETYPE_GENERALSTRING:
        case ASN1_ETYPE_NUMERIC_STRING:
        case ASN1_ETYPE_IA5_STRING:
        case ASN1_ETYPE_TELETEX_STRING:
        case ASN1_ETYPE_PRINTABLE_STRING:
        case ASN1_ETYPE_UNIVERSAL_STRING:
        case ASN1_ETYPE_BMP_STRING:
        case ASN1_ETYPE_UTF8_STRING:
        case ASN1_ETYPE_VISIBLE_STRING:
          if (len == 0)
    	len = _asn1_strlen (value);
          _asn1_set_value_lv (node, value, len);
          break;
        case ASN1_ETYPE_BIT_STRING:
          if (len == 0)
    	len = _asn1_strlen (value);
          asn1_length_der ((len >> 3) + 2, NULL, &len2);
          temp = malloc ((len >> 3) + 2 + len2);
          if (temp == NULL)
    	return ASN1_MEM_ALLOC_ERROR;

          asn1_bit_der (value, len, temp, &len2);
          _asn1_set_value_m (node, temp, len2);
          temp = NULL;
          break;
        case ASN1_ETYPE_CHOICE:
          p = node->down;
          while (p)
    	{
    	  if (!_asn1_strcmp (p->name, value))
    	    {
    	      p2 = node->down;
    	      while (p2)
    		{
    		  if (p2 != p)
    		    {
    		      asn1_delete_structure (&p2);
    		      p2 = node->down;
    		    }
    		  else
    		    p2 = p2->right;
    		}
    	      break;
    	    }
    	  p = p->right;
    	}
          if (!p)
    	return ASN1_ELEMENT_NOT_FOUND;
          break;
        case ASN1_ETYPE_ANY:
          _asn1_set_value_lv (node, value, len);
          break;
        case ASN1_ETYPE_SEQUENCE_OF:
        case ASN1_ETYPE_SET_OF:
          if (_asn1_strcmp (value, "NEW"))
    	return ASN1_VALUE_NOT_VALID;
          _asn1_append_sequence_set (node);
          break;
        default:
          return ASN1_ELEMENT_NOT_FOUND;
          break;
        }

      return ASN1_SUCCESS;
    }
↓ | asn1_print_structure | 82 | 216 | 327 | structure.c
    void
    asn1_print_structure (FILE * out, asn1_node structure, const char *name,
    		      int mode)
    {
      asn1_node p, root;
      int k, indent = 0, len, len2, len3;

      if (out == NULL)
        return;

      root = asn1_find_node (structure, name);

      if (root == NULL)
        return;

      p = root;
      while (p)
        {
          if (mode == ASN1_PRINT_ALL)
    	{
    	  for (k = 0; k < indent; k++)
    	    fprintf (out, " ");
    	  fprintf (out, "name:");
    	  if (p->name[0] != 0)
    	    fprintf (out, "%s  ", p->name);
    	  else
    	    fprintf (out, "NULL  ");
    	}
          else
    	{
    	  switch (type_field (p->type))
    	    {
    	    case ASN1_ETYPE_CONSTANT:
    	    case ASN1_ETYPE_TAG:
    	    case ASN1_ETYPE_SIZE:
    	      break;
    	    default:
    	      for (k = 0; k < indent; k++)
    		fprintf (out, " ");
    	      fprintf (out, "name:");
    	      if (p->name[0] != 0)
    		fprintf (out, "%s  ", p->name);
    	      else
    		fprintf (out, "NULL  ");
    	    }
    	}

          if (mode != ASN1_PRINT_NAME)
    	{
    	  unsigned type = type_field (p->type);
    	  switch (type)
    	    {
    	    case ASN1_ETYPE_CONSTANT:
    	      if (mode == ASN1_PRINT_ALL)
    		fprintf (out, "type:CONST");
    	      break;
    	    case ASN1_ETYPE_TAG:
    	      if (mode == ASN1_PRINT_ALL)
    		fprintf (out, "type:TAG");
    	      break;
    	    case ASN1_ETYPE_SIZE:
    	      if (mode == ASN1_PRINT_ALL)
    		fprintf (out, "type:SIZE");
    	      break;
    	    case ASN1_ETYPE_DEFAULT:
    	      fprintf (out, "type:DEFAULT");
    	      break;
    	    case ASN1_ETYPE_IDENTIFIER:
    	      fprintf (out, "type:IDENTIFIER");
    	      break;
    	    case ASN1_ETYPE_ANY:
    	      fprintf (out, "type:ANY");
    	      break;
    	    case ASN1_ETYPE_CHOICE:
    	      fprintf (out, "type:CHOICE");
    	      break;
    	    case ASN1_ETYPE_DEFINITIONS:
    	      fprintf (out, "type:DEFINITIONS");
    	      break;
    	    CASE_HANDLED_ETYPES:
    	      fprintf (out, "%s", _asn1_tags[type].desc);
    	      break;
    	    default:
    	      break;
    	    }
    	}

          if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
    	{
    	  switch (type_field (p->type))
    	    {
    	    case ASN1_ETYPE_CONSTANT:
    	      if (mode == ASN1_PRINT_ALL)
    		if (p->value)
    		  fprintf (out, "  value:%s", p->value);
    	      break;
    	    case ASN1_ETYPE_TAG:
    	      if (mode == ASN1_PRINT_ALL)
    		if (p->value)
    		  fprintf (out, "  value:%s", p->value);
    	      break;
    	    case ASN1_ETYPE_SIZE:
    	      if (mode == ASN1_PRINT_ALL)
    		if (p->value)
    		  fprintf (out, "  value:%s", p->value);
    	      break;
    	    case ASN1_ETYPE_DEFAULT:
    	      if (p->value)
    		fprintf (out, "  value:%s", p->value);
    	      else if (p->type & CONST_TRUE)
    		fprintf (out, "  value:TRUE");
    	      else if (p->type & CONST_FALSE)
    		fprintf (out, "  value:FALSE");
    	      break;
    	    case ASN1_ETYPE_IDENTIFIER:
    	      if (p->value)
    		fprintf (out, "  value:%s", p->value);
    	      break;
    	    case ASN1_ETYPE_INTEGER:
    	      if (p->value)
    		{
    		  len2 = -1;
    		  len = asn1_get_length_der (p->value, p->value_len, &len2);
    		  fprintf (out, "  value:0x");
    		  if (len > 0)
    		    for (k = 0; k < len; k++)
    		      fprintf (out, "%02x", (p->value)[k + len2]);
    		}
    	      break;
    	    case ASN1_ETYPE_ENUMERATED:
    	      if (p->value)
    		{
    		  len2 = -1;
    		  len = asn1_get_length_der (p->value, p->value_len, &len2);
    		  fprintf (out, "  value:0x");
    		  if (len > 0)
    		    for (k = 0; k < len; k++)
    		      fprintf (out, "%02x", (p->value)[k + len2]);
    		}
    	      break;
    	    case ASN1_ETYPE_BOOLEAN:
    	      if (p->value)
    		{
    		  if (p->value[0] == 'T')
    		    fprintf (out, "  value:TRUE");
    		  else if (p->value[0] == 'F')
    		    fprintf (out, "  value:FALSE");
    		}
    	      break;
    	    case ASN1_ETYPE_BIT_STRING:
    	      if (p->value)
    		{
    		  len2 = -1;
    		  len = asn1_get_length_der (p->value, p->value_len, &len2);
    		  if (len > 0)
    		    {
    		      fprintf (out, "  value(%i):",
    			       (len - 1) * 8 - (p->value[len2]));
    		      for (k = 1; k < len; k++)
    			fprintf (out, "%02x", (p->value)[k + len2]);
    		    }
    		}
    	      break;
    	    case ASN1_ETYPE_GENERALIZED_TIME:
    	    case ASN1_ETYPE_UTC_TIME:
    	      if (p->value)
    		{
    		  fprintf (out, "  value:");
    		  for (k = 0; k < p->value_len; k++)
    		    fprintf (out, "%c", (p->value)[k]);
    		}
    	      break;
    	    case ASN1_ETYPE_GENERALSTRING:
    	    case ASN1_ETYPE_NUMERIC_STRING:
    	    case ASN1_ETYPE_IA5_STRING:
    	    case ASN1_ETYPE_TELETEX_STRING:
    	    case ASN1_ETYPE_PRINTABLE_STRING:
    	    case ASN1_ETYPE_UNIVERSAL_STRING:
    	    case ASN1_ETYPE_UTF8_STRING:
    	    case ASN1_ETYPE_VISIBLE_STRING:
    	      if (p->value)
    		{
    		  len2 = -1;
    		  len = asn1_get_length_der (p->value, p->value_len, &len2);
    		  fprintf (out, "  value:");
    		  if (len > 0)
    		    for (k = 0; k < len; k++)
    		      fprintf (out, "%c", (p->value)[k + len2]);
    		}
    	      break;
    	    case ASN1_ETYPE_BMP_STRING:
    	    case ASN1_ETYPE_OCTET_STRING:
    	      if (p->value)
    		{
    		  len2 = -1;
    		  len = asn1_get_length_der (p->value, p->value_len, &len2);
    		  fprintf (out, "  value:");
    		  if (len > 0)
    		    for (k = 0; k < len; k++)
    		      fprintf (out, "%02x", (p->value)[k + len2]);
    		}
    	      break;
    	    case ASN1_ETYPE_OBJECT_ID:
    	      if (p->value)
    		fprintf (out, "  value:%s", p->value);
    	      break;
    	    case ASN1_ETYPE_ANY:
    	      if (p->value)
    		{
    		  len3 = -1;
    		  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
    		  fprintf (out, "  value:");
    		  if (len2 > 0)
    		    for (k = 0; k < len2; k++)
    		      fprintf (out, "%02x", (p->value)[k + len3]);
    		}
    	      break;
    	    case ASN1_ETYPE_SET:
    	    case ASN1_ETYPE_SET_OF:
    	    case ASN1_ETYPE_CHOICE:
    	    case ASN1_ETYPE_DEFINITIONS:
    	    case ASN1_ETYPE_SEQUENCE_OF:
    	    case ASN1_ETYPE_SEQUENCE:
    	    case ASN1_ETYPE_NULL:
    	      break;
    	    default:
    	      break;
    	    }
    	}

          if (mode == ASN1_PRINT_ALL)
    	{
    	  if (p->type & 0x1FFFFF00)
    	    {
    	      fprintf (out, "  attr:");
    	      if (p->type & CONST_UNIVERSAL)
    		fprintf (out, "UNIVERSAL,");
    	      if (p->type & CONST_PRIVATE)
    		fprintf (out, "PRIVATE,");
    	      if (p->type & CONST_APPLICATION)
    		fprintf (out, "APPLICATION,");
    	      if (p->type & CONST_EXPLICIT)
    		fprintf (out, "EXPLICIT,");
    	      if (p->type & CONST_IMPLICIT)
    		fprintf (out, "IMPLICIT,");
    	      if (p->type & CONST_TAG)
    		fprintf (out, "TAG,");
    	      if (p->type & CONST_DEFAULT)
    		fprintf (out, "DEFAULT,");
    	      if (p->type & CONST_TRUE)
    		fprintf (out, "TRUE,");
    	      if (p->type & CONST_FALSE)
    		fprintf (out, "FALSE,");
    	      if (p->type & CONST_LIST)
    		fprintf (out, "LIST,");
    	      if (p->type & CONST_MIN_MAX)
    		fprintf (out, "MIN_MAX,");
    	      if (p->type & CONST_OPTION)
    		fprintf (out, "OPTION,");
    	      if (p->type & CONST_1_PARAM)
    		fprintf (out, "1_PARAM,");
    	      if (p->type & CONST_SIZE)
    		fprintf (out, "SIZE,");
    	      if (p->type & CONST_DEFINED_BY)
    		fprintf (out, "DEF_BY,");
    	      if (p->type & CONST_GENERALIZED)
    		fprintf (out, "GENERALIZED,");
    	      if (p->type & CONST_UTC)
    		fprintf (out, "UTC,");
    	      if (p->type & CONST_SET)
    		fprintf (out, "SET,");
    	      if (p->type & CONST_NOT_USED)
    		fprintf (out, "NOT_USED,");
    	      if (p->type & CONST_ASSIGN)
    		fprintf (out, "ASSIGNMENT,");
    	    }
    	}

          if (mode == ASN1_PRINT_ALL)
    	{
    	  fprintf (out, "\n");
    	}
          else
    	{
    	  switch (type_field (p->type))
    	    {
    	    case ASN1_ETYPE_CONSTANT:
    	    case ASN1_ETYPE_TAG:
    	    case ASN1_ETYPE_SIZE:
    	      break;
    	    default:
    	      fprintf (out, "\n");
    	    }
    	}

          if (p->down)
    	{
    	  p = p->down;
    	  indent += 2;
    	}
          else if (p == root)
    	{
    	  p = NULL;
    	  break;
    	}
          else if (p->right)
    	p = p->right;
          else
    	{
    	  while (1)
    	    {
    	      p = _asn1_find_up (p);
    	      if (p == root)
    		{
    		  p = NULL;
    		  break;
    		}
    	      indent -= 2;
    	      if (p->right)
    		{
    		  p = p->right;
    		  break;
    		}
    	    }
    	}
        }
    }
↓ | asn1_der_decoding_startEnd | 72 | 172 | 315 | decoding.c
    int
    asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len,
    			    const char *name_element, int *start, int *end)
    {
      asn1_node node, node_to_find, p, p2, p3;
      int counter, len2, len3, len4, move, ris;
      unsigned char class;
      unsigned long tag;
      int indefinite;
      const unsigned char *der = ider;

      node = element;

      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      node_to_find = asn1_find_node (node, name_element);

      if (node_to_find == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      if (node_to_find == node)
        {
          *start = 0;
          *end = len - 1;
          return ASN1_SUCCESS;
        }

      if (node->type & CONST_OPTION)
        return ASN1_GENERIC_ERROR;

      counter = 0;
      move = DOWN;
      p = node;
      while (1)
        {
          if (p == NULL)
    	return ASN1_DER_ERROR;

          ris = ASN1_SUCCESS;

          if (move != UP)
    	{
    	  if (p->type & CONST_SET)
    	    {
    	      p2 = _asn1_find_up (p);
    	      if (p2 == NULL)
    		return ASN1_DER_ERROR;

    	      len2 = _asn1_strtol (p2->value, NULL, 10);
    	      if (len2 == -1)
    		{
    		  if (!der[counter] && !der[counter + 1])
    		    {
    		      p = p2;
    		      move = UP;
    		      counter += 2;
    		      continue;
    		    }
    		}
    	      else if (counter == len2)
    		{
    		  p = p2;
    		  move = UP;
    		  continue;
    		}
    	      else if (counter > len2)
    		return ASN1_DER_ERROR;

    	      p2 = p2->down;

    	      while (p2)
    		{
    		  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
    		    {		/* CONTROLLARE */
    		      if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
    			ris =
    			  _asn1_extract_tag_der (p2, der + counter,
    						 len - counter, &len2);
    		      else
    			{
    			  p3 = p2->down;
    			  if (p3 == NULL)
    			    return ASN1_DER_ERROR;

    			  ris =
    			    _asn1_extract_tag_der (p3, der + counter,
    						   len - counter, &len2);
    			}
    		      if (ris == ASN1_SUCCESS)
    			{
    			  p2->type &= ~CONST_NOT_USED;
    			  p = p2;
    			  break;
    			}
    		    }
    		  p2 = p2->right;
    		}
    	      if (p2 == NULL)
    		return ASN1_DER_ERROR;
    	    }

    	  if (p == node_to_find)
    	    *start = counter;

    	  if (type_field (p->type) == ASN1_ETYPE_CHOICE)
    	    {
    	      p = p->down;
    	      if (p == NULL)
    		return ASN1_DER_ERROR;

    	      ris =
    		_asn1_extract_tag_der (p, der + counter, len - counter,
    				       &len2);
    	      if (p == node_to_find)
    		*start = counter;
    	    }

    	  if (ris == ASN1_SUCCESS)
    	    ris =
    	      _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
    	  if (ris != ASN1_SUCCESS)
    	    {
    	      if (p->type & CONST_OPTION)
    		{
    		  p->type |= CONST_NOT_USED;
    		  move = RIGHT;
    		}
    	      else if (p->type & CONST_DEFAULT)
    		{
    		  move = RIGHT;
    		}
    	      else
    		{
    		  return ASN1_TAG_ERROR;
    		}
    	    }
    	  else
    	    counter += len2;
    	}

          if (ris == ASN1_SUCCESS)
    	{
    	  switch (type_field (p->type))
    	    {
    	    case ASN1_ETYPE_NULL:
    	      if (der[counter])
    		return ASN1_DER_ERROR;
    	      counter++;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_BOOLEAN:
    	      if (der[counter++] != 1)
    		return ASN1_DER_ERROR;
    	      counter++;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_OCTET_STRING:
    	      len3 = len - counter;
    	      ris = _asn1_get_octet_string (der + counter, NULL, &len3);
    	      if (ris != ASN1_SUCCESS)
    		return ris;
    	      counter += len3;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_UTC_TIME:
    	    case ASN1_ETYPE_GENERALIZED_TIME:
    	    case ASN1_ETYPE_OBJECT_ID:
    	    case ASN1_ETYPE_INTEGER:
    	    case ASN1_ETYPE_ENUMERATED:
    	    case ASN1_ETYPE_GENERALSTRING:
    	    case ASN1_ETYPE_NUMERIC_STRING:
    	    case ASN1_ETYPE_IA5_STRING:
    	    case ASN1_ETYPE_TELETEX_STRING:
    	    case ASN1_ETYPE_PRINTABLE_STRING:
    	    case ASN1_ETYPE_UNIVERSAL_STRING:
    	    case ASN1_ETYPE_BMP_STRING:
    	    case ASN1_ETYPE_UTF8_STRING:
    	    case ASN1_ETYPE_VISIBLE_STRING:
    	    case ASN1_ETYPE_BIT_STRING:
    	      len2 =
    		asn1_get_length_der (der + counter, len - counter, &len3);
    	      if (len2 < 0)
    		return ASN1_DER_ERROR;
    	      counter += len3 + len2;
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_SEQUENCE:
    	    case ASN1_ETYPE_SET:
    	      if (move != UP)
    		{
    		  len3 =
    		    asn1_get_length_der (der + counter, len - counter, &len2);
    		  if (len3 < -1)
    		    return ASN1_DER_ERROR;
    		  counter += len2;
    		  if (len3 == 0)
    		    move = RIGHT;
    		  else
    		    move = DOWN;
    		}
    	      else
    		{
    		  if (!der[counter] && !der[counter + 1])	/* indefinite length method */
    		    counter += 2;
    		  move = RIGHT;
    		}
    	      break;
    	    case ASN1_ETYPE_SEQUENCE_OF:
    	    case ASN1_ETYPE_SET_OF:
    	      if (move != UP)
    		{
    		  len3 =
    		    asn1_get_length_der (der + counter, len - counter, &len2);
    		  if (len3 < -1)
    		    return ASN1_DER_ERROR;
    		  counter += len2;
    		  if ((len3 == -1) && !der[counter] && !der[counter + 1])
    		    counter += 2;
    		  else if (len3)
    		    {
    		      p2 = p->down;
    		      while ((type_field (p2->type) == ASN1_ETYPE_TAG) ||
    			     (type_field (p2->type) == ASN1_ETYPE_SIZE))
    			p2 = p2->right;
    		      p = p2;
    		    }
    		}
    	      else
    		{
    		  if (!der[counter] && !der[counter + 1])	/* indefinite length method */
    		    counter += 2;
    		}
    	      move = RIGHT;
    	      break;
    	    case ASN1_ETYPE_ANY:
    	      if (asn1_get_tag_der
    		  (der + counter, len - counter, &class, &len2,
    		   &tag) != ASN1_SUCCESS)
    		return ASN1_DER_ERROR;
    	      if (counter + len2 > len)
    		return ASN1_DER_ERROR;

    	      len4 =
    		asn1_get_length_der (der + counter + len2,
    				     len - counter - len2, &len3);
    	      if (len4 < -1)
    		return ASN1_DER_ERROR;

    	      if (len4 != -1)
    		{
    		  counter += len2 + len4 + len3;
    		}
    	      else
    		{		/* indefinite length */
    		  /* Check indefinite lenth method in an EXPLICIT TAG */
    		  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
    		    indefinite = 1;
    		  else
    		    indefinite = 0;

    		  len2 = len - counter;
    		  ris =
    		    _asn1_get_indefinite_length_string (der + counter, &len2);
    		  if (ris != ASN1_SUCCESS)
    		    return ris;
    		  counter += len2;

    		  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
    		     an indefinite length method. */
    		  if (indefinite)
    		    {
    		      if (!der[counter] && !der[counter + 1])
    			counter += 2;
    		      else
    			return ASN1_DER_ERROR;
    		    }
    		}
    	      move = RIGHT;
    	      break;
    	    default:
    	      move = (move == UP) ? RIGHT : DOWN;
    	      break;
    	    }
    	}

          if ((p == node_to_find) && (move == RIGHT))
    	{
    	  *end = counter - 1;
    	  return ASN1_SUCCESS;
    	}

          if (p == node && move != DOWN)
    	break;

          if (move == DOWN)
    	{
    	  if (p->down)
    	    p = p->down;
    	  else
    	    move = RIGHT;
    	}
          if ((move == RIGHT) && !(p->type & CONST_SET))
    	{
    	  if (p->right)
    	    p = p->right;
    	  else
    	    move = UP;
    	}
          if (move == UP)
    	p = _asn1_find_up (p);
        }

      return ASN1_ELEMENT_NOT_FOUND;
    }
↓ | asn1_der_coding | 64 | 198 | 330 | coding.c
    int
    asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
    		 char *ErrorDescription)
    {
      asn1_node node, p, p2;
      unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
      int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
      int err;
      unsigned char *der = ider;

      node = asn1_find_node (element, name);
      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      /* Node is now a locally allocated variable.
       * That is because in some point we modify the
       * structure, and I don't know why! --nmav
       */
      node = _asn1_copy_structure3 (node);
      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      max_len = *len;

      counter = 0;
      move = DOWN;
      p = node;
      while (1)
        {

          counter_old = counter;
          max_len_old = max_len;
          if (move != UP)
    	{
    	  err = _asn1_insert_tag_der (p, der, &counter, &max_len);
    	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
    	    goto error;
    	}
          switch (type_field (p->type))
    	{
    	case ASN1_ETYPE_NULL:
    	  max_len--;
    	  if (max_len >= 0)
    	    der[counter] = 0;
    	  counter++;
    	  move = RIGHT;
    	  break;
    	case ASN1_ETYPE_BOOLEAN:
    	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
    	    {
    	      counter = counter_old;
    	      max_len = max_len_old;
    	    }
    	  else
    	    {
    	      if (p->value == NULL)
    		{
    		  _asn1_error_description_value_not_found (p,
    							   ErrorDescription);
    		  err = ASN1_VALUE_NOT_FOUND;
    		  goto error;
    		}
    	      max_len -= 2;
    	      if (max_len >= 0)
    		{
    		  der[counter++] = 1;
    		  if (p->value[0] == 'F')
    		    der[counter++] = 0;
    		  else
    		    der[counter++] = 0xFF;
    		}
    	      else
    		counter += 2;
    	    }
    	  move = RIGHT;
    	  break;
    	case ASN1_ETYPE_INTEGER:
    	case ASN1_ETYPE_ENUMERATED:
    	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
    	    {
    	      counter = counter_old;
    	      max_len = max_len_old;
    	    }
    	  else
    	    {
    	      if (p->value == NULL)
    		{
    		  _asn1_error_description_value_not_found (p,
    							   ErrorDescription);
    		  err = ASN1_VALUE_NOT_FOUND;
    		  goto error;
    		}
    	      len2 = asn1_get_length_der (p->value, p->value_len, &len3);
    	      if (len2 < 0)
    		{
    		  err = ASN1_DER_ERROR;
    		  goto error;
    		}
    	      max_len -= len2 + len3;
    	      if (max_len >= 0)
    		memcpy (der + counter, p->value, len3 + len2);
    	      counter += len3 + len2;
    	    }
    	  move = RIGHT;
    	  break;
    	case ASN1_ETYPE_OBJECT_ID:
    	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
    	    {
    	      counter = counter_old;
    	      max_len = max_len_old;
    	    }
    	  else
    	    {
    	      if (p->value == NULL)
    		{
    		  _asn1_error_description_value_not_found (p,
    							   ErrorDescription);
    		  err = ASN1_VALUE_NOT_FOUND;
    		  goto error;
    		}
    	      len2 = max_len;
    	      err = _asn1_objectid_der (p->value, der + counter, &len2);
    	      if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
    		goto error;

    	      max_len -= len2;
    	      counter += len2;
    	    }
    	  move = RIGHT;
    	  break;
    	case ASN1_ETYPE_GENERALIZED_TIME:
    	case ASN1_ETYPE_UTC_TIME:
    	  if (p->value == NULL)
    	    {
    	      _asn1_error_description_value_not_found (p, ErrorDescription);
    	      err = ASN1_VALUE_NOT_FOUND;
    	      goto error;
    	    }
    	  len2 = max_len;
    	  err = _asn1_time_der (p->value, p->value_len, der + counter, &len2);
    	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
    	    goto error;

    	  max_len -= len2;
    	  counter += len2;
    	  move = RIGHT;
    	  break;
    	case ASN1_ETYPE_OCTET_STRING:
    	case ASN1_ETYPE_GENERALSTRING:
    	case ASN1_ETYPE_NUMERIC_STRING:
    	case ASN1_ETYPE_IA5_STRING:
    	case ASN1_ETYPE_TELETEX_STRING:
    	case ASN1_ETYPE_PRINTABLE_STRING:
    	case ASN1_ETYPE_UNIVERSAL_STRING:
    	case ASN1_ETYPE_BMP_STRING:
    	case ASN1_ETYPE_UTF8_STRING:
    	case ASN1_ETYPE_VISIBLE_STRING:
    	case ASN1_ETYPE_BIT_STRING:
    	  if (p->value == NULL)
    	    {
    	      _asn1_error_description_value_not_found (p, ErrorDescription);
    	      err = ASN1_VALUE_NOT_FOUND;
    	      goto error;
    	    }
    	  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
    	  if (len2 < 0)
    	    {
    	      err = ASN1_DER_ERROR;
    	      goto error;
    	    }
    	  max_len -= len2 + len3;
    	  if (max_len >= 0)
    	    memcpy (der + counter, p->value, len3 + len2);
    	  counter += len3 + len2;
    	  move = RIGHT;
    	  break;
    	case ASN1_ETYPE_SEQUENCE:
    	case ASN1_ETYPE_SET:
    	  if (move != UP)
    	    {
    	      _asn1_ltostr (counter, (char *) temp);
    	      tlen = _asn1_strlen (temp);
    	      if (tlen > 0)
    		_asn1_set_value (p, temp, tlen + 1);
    	      if (p->down == NULL)
    		{
    		  move = UP;
    		  continue;
    		}
    	      else
    		{
    		  p2 = p->down;
    		  while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG))
    		    p2 = p2->right;
    		  if (p2)
    		    {
    		      p = p2;
    		      move = RIGHT;
    		      continue;
    		    }
    		  move = UP;
    		  continue;
    		}
    	    }
    	  else
    	    {			/* move==UP */
    	      len2 = _asn1_strtol (p->value, NULL, 10);
    	      _asn1_set_value (p, NULL, 0);
    	      if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0))
    		_asn1_ordering_set (der + len2, max_len - len2, p);
    	      asn1_length_der (counter - len2, temp, &len3);
    	      max_len -= len3;
    	      if (max_len >= 0)
    		{
    		  memmove (der + len2 + len3, der + len2, counter - len2);
    		  memcpy (der + len2, temp, len3);
    		}
    	      counter += len3;
    	      move = RIGHT;
    	    }
    	  break;
    	case ASN1_ETYPE_SEQUENCE_OF:
    	case ASN1_ETYPE_SET_OF:
    	  if (move != UP)
    	    {
    	      _asn1_ltostr (counter, (char *) temp);
    	      tlen = _asn1_strlen (temp);

    	      if (tlen > 0)
    		_asn1_set_value (p, temp, tlen + 1);
    	      p = p->down;
    	      while ((type_field (p->type) == ASN1_ETYPE_TAG)
    		     || (type_field (p->type) == ASN1_ETYPE_SIZE))
    		p = p->right;
    	      if (p->right)
    		{
    		  p = p->right;
    		  move = RIGHT;
    		  continue;
    		}
    	      else
    		p = _asn1_find_up (p);
    	      move = UP;
    	    }
    	  if (move == UP)
    	    {
    	      len2 = _asn1_strtol (p->value, NULL, 10);
    	      _asn1_set_value (p, NULL, 0);
    	      if ((type_field (p->type) == ASN1_ETYPE_SET_OF)
    		  && (max_len - len2 > 0))
    		{
    		  _asn1_ordering_set_of (der + len2, max_len - len2, p);
    		}
    	      asn1_length_der (counter - len2, temp, &len3);
    	      max_len -= len3;
    	      if (max_len >= 0)
    		{
    		  memmove (der + len2 + len3, der + len2, counter - len2);
    		  memcpy (der + len2, temp, len3);
    		}
    	      counter += len3;
    	      move = RIGHT;
    	    }
    	  break;
    	case ASN1_ETYPE_ANY:
    	  if (p->value == NULL)
    	    {
    	      _asn1_error_description_value_not_found (p, ErrorDescription);
    	      err = ASN1_VALUE_NOT_FOUND;
    	      goto error;
    	    }
    	  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
    	  if (len2 < 0)
    	    {
    	      err = ASN1_DER_ERROR;
    	      goto error;
    	    }
    	  max_len -= len2;
    	  if (max_len >= 0)
    	    memcpy (der + counter, p->value + len3, len2);
    	  counter += len2;
    	  move = RIGHT;
    	  break;
    	default:
    	  move = (move == UP) ? RIGHT : DOWN;
    	  break;
    	}

          if ((move != DOWN) && (counter != counter_old))
    	{
    	  err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
    	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
    	    goto error;
    	}

          if (p == node && move != DOWN)
    	break;

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

      *len = counter;

      if (max_len < 0)
        {
          err = ASN1_MEM_ERROR;
          goto error;
        }

      err = ASN1_SUCCESS;

    error:
      asn1_delete_structure (&node);
      return err;
    }
↓ | _asn1_expand_object_id | 44 | 95 | 173 | parser_aux.c
    int
    _asn1_expand_object_id (asn1_node node)
    {
      asn1_node 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) == ASN1_ETYPE_OBJECT_ID)
    	      && (p->type & CONST_ASSIGN))
    	    {
    	      p2 = p->down;
    	      if (p2 && (type_field (p2->type) == ASN1_ETYPE_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) != ASN1_ETYPE_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) == ASN1_ETYPE_CONSTANT)
    			    {
    			      p5 =
    				_asn1_add_single_node (ASN1_ETYPE_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) == ASN1_ETYPE_OBJECT_ID) &&
    	      (p->type & CONST_DEFAULT))
    	    {
    	      p2 = p->down;
    	      if (p2 && (type_field (p2->type) == ASN1_ETYPE_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) != ASN1_ETYPE_OBJECT_ID)
    		      || !(p3->type & CONST_ASSIGN))
    		    return ASN1_ELEMENT_NOT_FOUND;
    		  p4 = p3->down;
    		  name2[0] = 0;
    		  while (p4)
    		    {
    		      if (type_field (p4->type) == ASN1_ETYPE_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;
    }
↓ | _asn1_yylex | 44 | 54 | 95 | ASN1.c
    static int
    _asn1_yylex ()
    {
      int c, counter = 0, k, lastc;
      char string[ASN1_MAX_NAME_SIZE + 1];  /* will contain the next token */
      size_t i;

      while (1)
        {
          while ((c = fgetc (file_asn1)) == ' ' || c == '\t' || c == '\n')
            if (c == '\n')
              line_number++;

          if (c == EOF)
            {
              strcpy (last_token, "End Of File");
              return 0;
            }

          if (c == '(' || c == ')' || c == '[' || c == ']' ||
              c == '{' || c == '}' || c == ',' || c == '.' ||
              c == '+' || c == '|')
            {
              last_token[0] = c;
              last_token[1] = 0;
              return c;
            }
          if (c == '-')
            {                       /* Maybe the first '-' of a comment */
              if ((c = fgetc (file_asn1)) != '-')
                {
                  ungetc (c, file_asn1);
                  last_token[0] = '-';
                  last_token[1] = 0;
                  return '-';
                }
              else
                {                   /* Comments */
                  lastc = 0;
                  counter = 0;
                  /* A comment finishes at the next double hypen or the end of line */
                  while ((c = fgetc (file_asn1)) != EOF && c != '\n' &&
                         (lastc != '-' || (lastc == '-' && c != '-')))
                    lastc = c;
                  if (c == EOF)
                    {
                      strcpy (last_token, "End Of File");
                      return 0;
                    }
                  else
                    {
                      if (c == '\n')
                        line_number++;
                      continue;     /* next char, please! (repeat the search) */
                    }
                }
            }
          string[counter++] = c;
          /* Till the end of the token */
          while (!
                 ((c = fgetc (file_asn1)) == EOF || c == ' ' || c == '\t'
                  || c == '\n' || c == '(' || c == ')' || c == '[' || c == ']'
                  || c == '{' || c == '}' || c == ',' || c == '.'))
            {
              if (counter >= ASN1_MAX_NAME_SIZE)
                {
                  result_parse = ASN1_NAME_TOO_LONG;
                  return 0;
                }
              string[counter++] = c;
            }
          ungetc (c, file_asn1);
          string[counter] = 0;
          strcpy (last_token, string);

          /* Is STRING a number? */
          for (k = 0; k < counter; k++)
            if (!isdigit (string[k]))
              break;
          if (k >= counter)
            {
              strcpy (yylval.str, string);
              return NUM;           /* return the number */
            }

          /* Is STRING a keyword? */
          for (i = 0; i < (sizeof (key_word) / sizeof (char *)); i++)
            if (!strcmp (string, key_word[i]))
              return key_word_token[i];

          /* STRING is an IDENTIFIER */
          strcpy (yylval.str, string);
          return IDENTIFIER;
        }
    }
↓ | yyparse | 44 | 496 | 1407 | ASN1.c
    int
    yyparse (void *YYPARSE_PARAM)
    #else
    int
    yyparse (YYPARSE_PARAM)
        void *YYPARSE_PARAM;
    #endif
    #else /* ! YYPARSE_PARAM */
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    int
    yyparse (void)
    #else
    int
    yyparse ()

    #endif
    #endif
    {
        int yystate;
        /* Number of tokens to shift before error messages enabled.  */
        int yyerrstatus;

        /* The stacks and their tools:
           `yyss': related to states.
           `yyvs': related to semantic values.

           Refer to the stacks thru separate pointers, to allow yyoverflow
           to reallocate them elsewhere.  */

        /* The state stack.  */
        yytype_int16 yyssa[YYINITDEPTH];
        yytype_int16 *yyss;
        yytype_int16 *yyssp;

        /* The semantic value stack.  */
        YYSTYPE yyvsa[YYINITDEPTH];
        YYSTYPE *yyvs;
        YYSTYPE *yyvsp;

        YYSIZE_T yystacksize;

      int yyn;
      int yyresult;
      /* Lookahead token as an internal (translated) token number.  */
      int yytoken;
      /* The variables used to return semantic value and location from the
         action routines.  */
      YYSTYPE yyval;

    #if YYERROR_VERBOSE
      /* Buffer for error messages, and its allocated size.  */
      char yymsgbuf[128];
      char *yymsg = yymsgbuf;
      YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
    #endif

    #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))

      /* The number of symbols on the RHS of the reduced rule.
         Keep to zero when no symbol should be popped.  */
      int yylen = 0;

      yytoken = 0;
      yyss = yyssa;
      yyvs = yyvsa;
      yystacksize = YYINITDEPTH;

      YYDPRINTF ((stderr, "Starting parse\n"));

      yystate = 0;
      yyerrstatus = 0;
      yynerrs = 0;
      yychar = YYEMPTY; /* Cause a token to be read.  */

      /* Initialize stack pointers.
         Waste one element of value and location stack
         so that they stay on the same level as the state stack.
         The wasted elements are never initialized.  */
      yyssp = yyss;
      yyvsp = yyvs;

      goto yysetstate;

    /*------------------------------------------------------------.
    | yynewstate -- Push a new state, which is found in yystate.  |
    `------------------------------------------------------------*/
     yynewstate:
      /* In all cases, when you get here, the value and location stacks
         have just been pushed.  So pushing a state here evens the stacks.  */
      yyssp++;

     yysetstate:
      *yyssp = yystate;

      if (yyss + yystacksize - 1 <= yyssp)
        {
          /* Get the current used size of the three stacks, in elements.  */
          YYSIZE_T yysize = yyssp - yyss + 1;

    #ifdef yyoverflow
          {
    	/* Give user a chance to reallocate the stack.  Use copies of
    	   these so that the &'s don't force the real ones into
    	   memory.  */
    	YYSTYPE *yyvs1 = yyvs;
    	yytype_int16 *yyss1 = yyss;

    	/* Each stack pointer address is followed by the size of the
    	   data in use in that stack, in bytes.  This used to be a
    	   conditional around just the two extra args, but that might
    	   be undefined if yyoverflow is a macro.  */
    	yyoverflow (YY_("memory exhausted"),
    		    &yyss1, yysize * sizeof (*yyssp),
    		    &yyvs1, yysize * sizeof (*yyvsp),
    		    &yystacksize);

    	yyss = yyss1;
    	yyvs = yyvs1;
          }
    #else /* no yyoverflow */
    # ifndef YYSTACK_RELOCATE
          goto yyexhaustedlab;
    # else
          /* Extend the stack our own way.  */
          if (YYMAXDEPTH <= yystacksize)
    	goto yyexhaustedlab;
          yystacksize *= 2;
          if (YYMAXDEPTH < yystacksize)
    	yystacksize = YYMAXDEPTH;

          {
    	yytype_int16 *yyss1 = yyss;
    	union yyalloc *yyptr =
    	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
    	if (! yyptr)
    	  goto yyexhaustedlab;
    	YYSTACK_RELOCATE (yyss_alloc, yyss);
    	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
    #  undef YYSTACK_RELOCATE
    	if (yyss1 != yyssa)
    	  YYSTACK_FREE (yyss1);
          }
    # endif
    #endif /* no yyoverflow */

          yyssp = yyss + yysize - 1;
          yyvsp = yyvs + yysize - 1;

          YYDPRINTF ((stderr, "Stack size increased to %lu\n",
    		  (unsigned long int) yystacksize));

          if (yyss + yystacksize - 1 <= yyssp)
    	YYABORT;
        }

      YYDPRINTF ((stderr, "Entering state %d\n", yystate));

      if (yystate == YYFINAL)
        YYACCEPT;

      goto yybackup;

    /*-----------.
    | yybackup.  |
    `-----------*/
    yybackup:

      /* Do appropriate processing given the current state.  Read a
         lookahead token if we need one and don't already have one.  */

      /* First try to decide what to do without reference to lookahead token.  */
      yyn = yypact[yystate];
      if (yypact_value_is_default (yyn))
        goto yydefault;

      /* Not known => get a lookahead token if don't already have one.  */

      /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
      if (yychar == YYEMPTY)
        {
          YYDPRINTF ((stderr, "Reading a token: "));
          yychar = YYLEX;
        }

      if (yychar <= YYEOF)
        {
          yychar = yytoken = YYEOF;
          YYDPRINTF ((stderr, "Now at end of input.\n"));
        }
      else
        {
          yytoken = YYTRANSLATE (yychar);
          YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
        }

      /* If the proper action on seeing token YYTOKEN is to reduce or to
         detect an error, take that action.  */
      yyn += yytoken;
      if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
        goto yydefault;
      yyn = yytable[yyn];
      if (yyn <= 0)
        {
          if (yytable_value_is_error (yyn))
            goto yyerrlab;
          yyn = -yyn;
          goto yyreduce;
        }

      /* Count tokens shifted since error; after three, turn off error
         status.  */
      if (yyerrstatus)
        yyerrstatus--;

      /* Shift the lookahead token.  */
      YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);

      /* Discard the shifted token.  */
      yychar = YYEMPTY;

      yystate = yyn;
      *++yyvsp = yylval;

      goto yynewstate;

    /*-----------------------------------------------------------.
    | yydefault -- do the default action for the current state.  |
    `-----------------------------------------------------------*/
    yydefault:
      yyn = yydefact[yystate];
      if (yyn == 0)
        goto yyerrlab;
      goto yyreduce;

    /*-----------------------------.
    | yyreduce -- Do a reduction.  |
    `-----------------------------*/
    yyreduce:
      /* yyn is the number of a rule to reduce with.  */
      yylen = yyr2[yyn];

      /* If YYLEN is nonzero, implement the default value of the action:
         `$$ = $1'.

         Otherwise, the following line sets YYVAL to garbage.
         This behavior is undocumented and Bison
         users should not rely upon it.  Assigning to YYVAL
         unconditionally makes the parser a bit smaller, and it avoids a
         GCC warning that YYVAL may be used uninitialized.  */
      yyval = yyvsp[1-yylen];

      YY_REDUCE_PRINT (yyn);
      switch (yyn)
        {
            case 2:

    /* Line 1806 of yacc.c  */
    #line 137 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_DEFINITIONS|(yyvsp[(3) - (8)].constant));
                        _asn1_set_name((yyval.node),_asn1_get_name((yyvsp[(1) - (8)].node)));
                        _asn1_set_name((yyvsp[(1) - (8)].node),"");
                        _asn1_set_right((yyvsp[(1) - (8)].node),(yyvsp[(7) - (8)].node));
                        _asn1_set_down((yyval.node),(yyvsp[(1) - (8)].node));

    		    p_tree=(yyval.node);
    		    }
        break;

      case 3:

    /* Line 1806 of yacc.c  */
    #line 147 "ASN1.y"
        {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
        break;

      case 4:

    /* Line 1806 of yacc.c  */
    #line 148 "ASN1.y"
        {strcpy((yyval.str),(yyvsp[(2) - (2)].str));}
        break;

      case 5:

    /* Line 1806 of yacc.c  */
    #line 151 "ASN1.y"
        {strcpy((yyval.str),"-");
                           strcat((yyval.str),(yyvsp[(2) - (2)].str));}
        break;

      case 6:

    /* Line 1806 of yacc.c  */
    #line 155 "ASN1.y"
        {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
        break;

      case 7:

    /* Line 1806 of yacc.c  */
    #line 156 "ASN1.y"
        {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
        break;

      case 8:

    /* Line 1806 of yacc.c  */
    #line 159 "ASN1.y"
        {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
        break;

      case 9:

    /* Line 1806 of yacc.c  */
    #line 160 "ASN1.y"
        {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
        break;

      case 10:

    /* Line 1806 of yacc.c  */
    #line 163 "ASN1.y"
        {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
        break;

      case 11:

    /* Line 1806 of yacc.c  */
    #line 164 "ASN1.y"
        {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
        break;

      case 12:

    /* Line 1806 of yacc.c  */
    #line 167 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
                                           _asn1_set_value((yyval.node),(yyvsp[(2) - (3)].str),strlen((yyvsp[(2) - (3)].str))+1);}
        break;

      case 13:

    /* Line 1806 of yacc.c  */
    #line 169 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
    	                               _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
                                           _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
        break;

      case 14:

    /* Line 1806 of yacc.c  */
    #line 174 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 15:

    /* Line 1806 of yacc.c  */
    #line 175 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (3)].node);
                                                _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
        break;

      case 16:

    /* Line 1806 of yacc.c  */
    #line 179 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
                                       _asn1_set_value((yyval.node),(yyvsp[(1) - (1)].str),strlen((yyvsp[(1) - (1)].str))+1);}
        break;

      case 17:

    /* Line 1806 of yacc.c  */
    #line 181 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
    	                            _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
                                        _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
        break;

      case 18:

    /* Line 1806 of yacc.c  */
    #line 186 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 19:

    /* Line 1806 of yacc.c  */
    #line 187 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (2)].node);
                                                        _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (2)].node)),(yyvsp[(2) - (2)].node));}
        break;

      case 20:

    /* Line 1806 of yacc.c  */
    #line 191 "ASN1.y"
        {(yyval.constant)=CONST_UNIVERSAL;}
        break;

      case 21:

    /* Line 1806 of yacc.c  */
    #line 192 "ASN1.y"
        {(yyval.constant)=CONST_PRIVATE;}
        break;

      case 22:

    /* Line 1806 of yacc.c  */
    #line 193 "ASN1.y"
        {(yyval.constant)=CONST_APPLICATION;}
        break;

      case 23:

    /* Line 1806 of yacc.c  */
    #line 196 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TAG);
                                _asn1_set_value((yyval.node),(yyvsp[(2) - (3)].str),strlen((yyvsp[(2) - (3)].str))+1);}
        break;

      case 24:

    /* Line 1806 of yacc.c  */
    #line 198 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TAG | (yyvsp[(2) - (4)].constant));
                                    _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
        break;

      case 25:

    /* Line 1806 of yacc.c  */
    #line 202 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 26:

    /* Line 1806 of yacc.c  */
    #line 203 "ASN1.y"
        {(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_EXPLICIT);}
        break;

      case 27:

    /* Line 1806 of yacc.c  */
    #line 204 "ASN1.y"
        {(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_IMPLICIT);}
        break;

      case 28:

    /* Line 1806 of yacc.c  */
    #line 207 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_DEFAULT);
                                           _asn1_set_value((yyval.node),(yyvsp[(2) - (2)].str),strlen((yyvsp[(2) - (2)].str))+1);}
        break;

      case 29:

    /* Line 1806 of yacc.c  */
    #line 209 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_TRUE);}
        break;

      case 30:

    /* Line 1806 of yacc.c  */
    #line 210 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_FALSE);}
        break;

      case 33:

    /* Line 1806 of yacc.c  */
    #line 219 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
        break;

      case 34:

    /* Line 1806 of yacc.c  */
    #line 220 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_LIST);
    	                                 _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
        break;

      case 35:

    /* Line 1806 of yacc.c  */
    #line 222 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
        break;

      case 36:

    /* Line 1806 of yacc.c  */
    #line 224 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_MIN_MAX);
                                             _asn1_set_down((yyval.node),_asn1_add_static_node(ASN1_ETYPE_SIZE));
                                             _asn1_set_value(_asn1_get_down((yyval.node)),(yyvsp[(6) - (7)].str),strlen((yyvsp[(6) - (7)].str))+1);
                                             _asn1_set_name(_asn1_get_down((yyval.node)),(yyvsp[(3) - (7)].str));}
        break;

      case 37:

    /* Line 1806 of yacc.c  */
    #line 230 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BOOLEAN);}
        break;

      case 38:

    /* Line 1806 of yacc.c  */
    #line 233 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTC_TIME);}
        break;

      case 39:

    /* Line 1806 of yacc.c  */
    #line 234 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_GENERALIZED_TIME);}
        break;

      case 40:

    /* Line 1806 of yacc.c  */
    #line 237 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_1_PARAM);
    	                              _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
        break;

      case 41:

    /* Line 1806 of yacc.c  */
    #line 240 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_MIN_MAX);
    	                              _asn1_set_value((yyval.node),(yyvsp[(3) - (7)].str),strlen((yyvsp[(3) - (7)].str))+1);
                                          _asn1_set_name((yyval.node),(yyvsp[(6) - (7)].str));}
        break;

      case 42:

    /* Line 1806 of yacc.c  */
    #line 245 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 43:

    /* Line 1806 of yacc.c  */
    #line 246 "ASN1.y"
        {(yyval.node)=(yyvsp[(2) - (3)].node);}
        break;

      case 44:

    /* Line 1806 of yacc.c  */
    #line 249 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING);}
        break;

      case 45:

    /* Line 1806 of yacc.c  */
    #line 250 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 46:

    /* Line 1806 of yacc.c  */
    #line 254 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);}
        break;

      case 47:

    /* Line 1806 of yacc.c  */
    #line 255 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 48:

    /* Line 1806 of yacc.c  */
    #line 259 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING);}
        break;

      case 49:

    /* Line 1806 of yacc.c  */
    #line 260 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 50:

    /* Line 1806 of yacc.c  */
    #line 264 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING);}
        break;

      case 51:

    /* Line 1806 of yacc.c  */
    #line 265 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 52:

    /* Line 1806 of yacc.c  */
    #line 269 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING);}
        break;

      case 53:

    /* Line 1806 of yacc.c  */
    #line 270 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 54:

    /* Line 1806 of yacc.c  */
    #line 274 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING);}
        break;

      case 55:

    /* Line 1806 of yacc.c  */
    #line 275 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 56:

    /* Line 1806 of yacc.c  */
    #line 279 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING);}
        break;

      case 57:

    /* Line 1806 of yacc.c  */
    #line 280 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 58:

    /* Line 1806 of yacc.c  */
    #line 284 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING);}
        break;

      case 59:

    /* Line 1806 of yacc.c  */
    #line 285 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 60:

    /* Line 1806 of yacc.c  */
    #line 289 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING);}
        break;

      case 61:

    /* Line 1806 of yacc.c  */
    #line 290 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE);
    					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 62:

    /* Line 1806 of yacc.c  */
    #line 294 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING);}
        break;

      case 63:

    /* Line 1806 of yacc.c  */
    #line 295 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING|CONST_SIZE);
                                               _asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
        break;

      case 64:

    /* Line 1806 of yacc.c  */
    #line 299 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
    	                           _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
                                        _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
        break;

      case 65:

    /* Line 1806 of yacc.c  */
    #line 304 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 66:

    /* Line 1806 of yacc.c  */
    #line 305 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (3)].node);
                                                           _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
        break;

      case 67:

    /* Line 1806 of yacc.c  */
    #line 309 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING);}
        break;

      case 68:

    /* Line 1806 of yacc.c  */
    #line 310 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_SIZE);}
        break;

      case 69:

    /* Line 1806 of yacc.c  */
    #line 312 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_LIST);
                                    _asn1_set_down((yyval.node),(yyvsp[(4) - (5)].node));}
        break;

      case 70:

    /* Line 1806 of yacc.c  */
    #line 317 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_ENUMERATED|CONST_LIST);
                                    _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
        break;

      case 71:

    /* Line 1806 of yacc.c  */
    #line 322 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);}
        break;

      case 72:

    /* Line 1806 of yacc.c  */
    #line 325 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER);
                                           _asn1_set_value((yyval.node),(yyvsp[(1) - (1)].str),strlen((yyvsp[(1) - (1)].str))+1);}
        break;

      case 73:

    /* Line 1806 of yacc.c  */
    #line 327 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER|CONST_SIZE);
                                           _asn1_set_value((yyval.node),(yyvsp[(1) - (2)].str),strlen((yyvsp[(1) - (2)].str))+1);
                                           _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 74:

    /* Line 1806 of yacc.c  */
    #line 330 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 75:

    /* Line 1806 of yacc.c  */
    #line 331 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 76:

    /* Line 1806 of yacc.c  */
    #line 332 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 78:

    /* Line 1806 of yacc.c  */
    #line 334 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 79:

    /* Line 1806 of yacc.c  */
    #line 335 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 80:

    /* Line 1806 of yacc.c  */
    #line 336 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 81:

    /* Line 1806 of yacc.c  */
    #line 337 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 82:

    /* Line 1806 of yacc.c  */
    #line 338 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 83:

    /* Line 1806 of yacc.c  */
    #line 339 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 84:

    /* Line 1806 of yacc.c  */
    #line 340 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 85:

    /* Line 1806 of yacc.c  */
    #line 341 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 86:

    /* Line 1806 of yacc.c  */
    #line 342 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 87:

    /* Line 1806 of yacc.c  */
    #line 343 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 88:

    /* Line 1806 of yacc.c  */
    #line 344 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 89:

    /* Line 1806 of yacc.c  */
    #line 345 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 90:

    /* Line 1806 of yacc.c  */
    #line 346 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 91:

    /* Line 1806 of yacc.c  */
    #line 347 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 92:

    /* Line 1806 of yacc.c  */
    #line 348 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 93:

    /* Line 1806 of yacc.c  */
    #line 349 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 94:

    /* Line 1806 of yacc.c  */
    #line 350 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NULL);}
        break;

      case 95:

    /* Line 1806 of yacc.c  */
    #line 353 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 96:

    /* Line 1806 of yacc.c  */
    #line 354 "ASN1.y"
        {(yyval.node)=_asn1_mod_type((yyvsp[(2) - (2)].node),CONST_TAG);
                                                   _asn1_set_right((yyvsp[(1) - (2)].node),_asn1_get_down((yyval.node)));
                                                   _asn1_set_down((yyval.node),(yyvsp[(1) - (2)].node));}
        break;

      case 97:

    /* Line 1806 of yacc.c  */
    #line 359 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 98:

    /* Line 1806 of yacc.c  */
    #line 360 "ASN1.y"
        {(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_DEFAULT);
                                                           _asn1_set_right((yyvsp[(2) - (2)].node),_asn1_get_down((yyval.node)));
    						       _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
        break;

      case 99:

    /* Line 1806 of yacc.c  */
    #line 363 "ASN1.y"
        {(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_OPTION);}
        break;

      case 100:

    /* Line 1806 of yacc.c  */
    #line 366 "ASN1.y"
        {(yyval.node)=_asn1_set_name((yyvsp[(2) - (2)].node),(yyvsp[(1) - (2)].str));}
        break;

      case 101:

    /* Line 1806 of yacc.c  */
    #line 369 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 102:

    /* Line 1806 of yacc.c  */
    #line 370 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (3)].node);
                                                    _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
        break;

      case 103:

    /* Line 1806 of yacc.c  */
    #line 374 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE);
                                                  _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
        break;

      case 104:

    /* Line 1806 of yacc.c  */
    #line 376 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF);
                                                  _asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
        break;

      case 105:

    /* Line 1806 of yacc.c  */
    #line 378 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF|CONST_SIZE);
                                                _asn1_set_right((yyvsp[(2) - (4)].node),(yyvsp[(4) - (4)].node));
                                                _asn1_set_down((yyval.node),(yyvsp[(2) - (4)].node));}
        break;

      case 106:

    /* Line 1806 of yacc.c  */
    #line 383 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SET);
                                         _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
        break;

      case 107:

    /* Line 1806 of yacc.c  */
    #line 385 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SET_OF);
                                         _asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
        break;

      case 108:

    /* Line 1806 of yacc.c  */
    #line 387 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SET_OF|CONST_SIZE);
                                           _asn1_set_right((yyvsp[(2) - (4)].node),(yyvsp[(4) - (4)].node));
                                           _asn1_set_down((yyval.node),(yyvsp[(2) - (4)].node));}
        break;

      case 109:

    /* Line 1806 of yacc.c  */
    #line 392 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CHOICE);
                                                 _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
        break;

      case 110:

    /* Line 1806 of yacc.c  */
    #line 396 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_ANY);}
        break;

      case 111:

    /* Line 1806 of yacc.c  */
    #line 397 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_ANY|CONST_DEFINED_BY);
                                            _asn1_set_down((yyval.node),_asn1_add_static_node(ASN1_ETYPE_CONSTANT));
    	                                _asn1_set_name(_asn1_get_down((yyval.node)),(yyvsp[(4) - (4)].str));}
        break;

      case 112:

    /* Line 1806 of yacc.c  */
    #line 402 "ASN1.y"
        {(yyval.node)=_asn1_set_name((yyvsp[(3) - (3)].node),(yyvsp[(1) - (3)].str));}
        break;

      case 113:

    /* Line 1806 of yacc.c  */
    #line 404 "ASN1.y"
        {(yyval.node)=_asn1_set_name((yyvsp[(3) - (3)].node), last_error_token);}
        break;

      case 114:

    /* Line 1806 of yacc.c  */
    #line 408 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN);
                             _asn1_set_name((yyval.node),(yyvsp[(1) - (7)].str));
                             _asn1_set_down((yyval.node),(yyvsp[(6) - (7)].node));}
        break;

      case 115:

    /* Line 1806 of yacc.c  */
    #line 412 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
                             _asn1_set_name((yyval.node),(yyvsp[(1) - (6)].str));
                             _asn1_set_value((yyval.node),(yyvsp[(2) - (6)].str),strlen((yyvsp[(2) - (6)].str))+1);
                             _asn1_set_down((yyval.node),(yyvsp[(5) - (6)].node));}
        break;

      case 116:

    /* Line 1806 of yacc.c  */
    #line 417 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_ASSIGN);
                             _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
                             _asn1_set_value((yyval.node),(yyvsp[(4) - (4)].str),strlen((yyvsp[(4) - (4)].str))+1);}
        break;

      case 117:

    /* Line 1806 of yacc.c  */
    #line 422 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 118:

    /* Line 1806 of yacc.c  */
    #line 423 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 119:

    /* Line 1806 of yacc.c  */
    #line 426 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (1)].node);}
        break;

      case 120:

    /* Line 1806 of yacc.c  */
    #line 427 "ASN1.y"
        {(yyval.node)=(yyvsp[(1) - (2)].node);
                                                              _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (2)].node)),(yyvsp[(2) - (2)].node));}
        break;

      case 121:

    /* Line 1806 of yacc.c  */
    #line 431 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
                                                              _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));
                                                              _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));}
        break;

      case 122:

    /* Line 1806 of yacc.c  */
    #line 434 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
                                                              _asn1_set_name((yyval.node),(yyvsp[(1) - (3)].str));}
        break;

      case 123:

    /* Line 1806 of yacc.c  */
    #line 436 "ASN1.y"
        {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
                                                              _asn1_set_name((yyval.node),(yyvsp[(1) - (1)].str));}
        break;

      case 124:

    /* Line 1806 of yacc.c  */
    #line 460 "ASN1.y"
        {(yyval.constant)=CONST_EXPLICIT;}
        break;

      case 125:

    /* Line 1806 of yacc.c  */
    #line 461 "ASN1.y"
        {(yyval.constant)=CONST_IMPLICIT;}
        break;

    /* Line 1806 of yacc.c  */
    #line 2648 "ASN1.c"
          default: break;
        }
      /* User semantic actions sometimes alter yychar, and that requires
         that yytoken be updated with the new translation.  We take the
         approach of translating immediately before every use of yytoken.
         One alternative is translating here after every semantic action,
         but that translation would be missed if the semantic action invokes
         YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
         if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
         incorrect destructor might then be invoked immediately.  In the
         case of YYERROR or YYBACKUP, subsequent parser actions might lead
         to an incorrect destructor call or verbose syntax error message
         before the lookahead is translated.  */
      YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);

      YYPOPSTACK (yylen);
      yylen = 0;
      YY_STACK_PRINT (yyss, yyssp);

      *++yyvsp = yyval;

      /* Now `shift' the result of the reduction.  Determine what state
         that goes to, based on the state we popped back to and the rule
         number reduced by.  */

      yyn = yyr1[yyn];

      yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
      if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
        yystate = yytable[yystate];
      else
        yystate = yydefgoto[yyn - YYNTOKENS];

      goto yynewstate;

    /*------------------------------------.
    | yyerrlab -- here on detecting error |
    `------------------------------------*/
    yyerrlab:
      /* Make sure we have latest lookahead translation.  See comments at
         user semantic actions for why this is necessary.  */
      yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);

      /* If not already recovering from an error, report this error.  */
      if (!yyerrstatus)
        {
          ++yynerrs;
    #if ! YYERROR_VERBOSE
          yyerror (YY_("syntax error"));
    #else
    # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
                                            yyssp, yytoken)
          {
            char const *yymsgp = YY_("syntax error");
            int yysyntax_error_status;
            yysyntax_error_status = YYSYNTAX_ERROR;
            if (yysyntax_error_status == 0)
              yymsgp = yymsg;
            else if (yysyntax_error_status == 1)
              {
                if (yymsg != yymsgbuf)
                  YYSTACK_FREE (yymsg);
                yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
                if (!yymsg)
                  {
                    yymsg = yymsgbuf;
                    yymsg_alloc = sizeof yymsgbuf;
                    yysyntax_error_status = 2;
                  }
                else
                  {
                    yysyntax_error_status = YYSYNTAX_ERROR;
                    yymsgp = yymsg;
                  }
              }
            yyerror (yymsgp);
            if (yysyntax_error_status == 2)
              goto yyexhaustedlab;
          }
    # undef YYSYNTAX_ERROR
    #endif
        }

      if (yyerrstatus == 3)
        {
          /* If just tried and failed to reuse lookahead token after an
    	 error, discard it.  */

          if (yychar <= YYEOF)
    	{
    	  /* Return failure if at end of input.  */
    	  if (yychar == YYEOF)
    	    YYABORT;
    	}
          else
    	{
    	  yydestruct ("Error: discarding",
    		      yytoken, &yylval);
    	  yychar = YYEMPTY;
    	}
        }

      /* Else will try to reuse lookahead token after shifting the error
         token.  */
      goto yyerrlab1;

    /*---------------------------------------------------.
    | yyerrorlab -- error raised explicitly by YYERROR.  |
    `---------------------------------------------------*/
    yyerrorlab:

      /* Pacify compilers like GCC when the user code never invokes
         YYERROR and the label yyerrorlab therefore never appears in user
         code.  */
      if (/*CONSTCOND*/ 0)
         goto yyerrorlab;

      /* Do not reclaim the symbols of the rule which action triggered
         this YYERROR.  */
      YYPOPSTACK (yylen);
      yylen = 0;
      YY_STACK_PRINT (yyss, yyssp);
      yystate = *yyssp;
      goto yyerrlab1;

    /*-------------------------------------------------------------.
    | yyerrlab1 -- common code for both syntax error and YYERROR.  |
    `-------------------------------------------------------------*/
    yyerrlab1:
      yyerrstatus = 3;	/* Each real token shifted decrements this.  */

      for (;;)
        {
          yyn = yypact[yystate];
          if (!yypact_value_is_default (yyn))
    	{
    	  yyn += YYTERROR;
    	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
    	    {
    	      yyn = yytable[yyn];
    	      if (0 < yyn)
    		break;
    	    }
    	}

          /* Pop the current state because it cannot handle the error token.  */
          if (yyssp == yyss)
    	YYABORT;

          yydestruct ("Error: popping",
    		  yystos[yystate], yyvsp);
          YYPOPSTACK (1);
          yystate = *yyssp;
          YY_STACK_PRINT (yyss, yyssp);
        }

      *++yyvsp = yylval;

      /* Shift the error token.  */
      YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);

      yystate = yyn;
      goto yynewstate;

    /*-------------------------------------.
    | yyacceptlab -- YYACCEPT comes here.  |
    `-------------------------------------*/
    yyacceptlab:
      yyresult = 0;
      goto yyreturn;

    /*-----------------------------------.
    | yyabortlab -- YYABORT comes here.  |
    `-----------------------------------*/
    yyabortlab:
      yyresult = 1;
      goto yyreturn;

    #if !defined(yyoverflow) || YYERROR_VERBOSE
    /*-------------------------------------------------.
    | yyexhaustedlab -- memory exhaustion comes here.  |
    `-------------------------------------------------*/
    yyexhaustedlab:
      yyerror (YY_("memory exhausted"));
      yyresult = 2;
      /* Fall through.  */
    #endif

    yyreturn:
      if (yychar != YYEMPTY)
        {
          /* Make sure we have latest lookahead translation.  See comments at
             user semantic actions for why this is necessary.  */
          yytoken = YYTRANSLATE (yychar);
          yydestruct ("Cleanup: discarding lookahead",
                      yytoken, &yylval);
        }
      /* Do not reclaim the symbols of the rule which action triggered
         this YYABORT or YYACCEPT.  */
      YYPOPSTACK (yylen);
      YY_STACK_PRINT (yyss, yyssp);
      while (yyssp != yyss)
        {
          yydestruct ("Cleanup: popping",
    		  yystos[*yyssp], yyvsp);
          YYPOPSTACK (1);
        }
    #ifndef yyoverflow
      if (yyss != yyssa)
        YYSTACK_FREE (yyss);
    #endif
    #if YYERROR_VERBOSE
      if (yymsg != yymsgbuf)
        YYSTACK_FREE (yymsg);
    #endif
      /* Make sure YYID is used.  */
      return YYID (yyresult);
    }
↓ | asn1_expand_any_defined_by | 41 | 101 | 211 | decoding.c
    int
    asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
    {
      char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
        value[ASN1_MAX_NAME_SIZE];
      int retCode = ASN1_SUCCESS, result;
      int len, len2, len3;
      asn1_node p, p2, p3, aux = NULL;
      char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];

      if ((definitions == NULL) || (*element == NULL))
        return ASN1_ELEMENT_NOT_FOUND;

      strcpy (definitionsName, definitions->name);
      strcat (definitionsName, ".");

      p = *element;
      while (p)
        {

          switch (type_field (p->type))
    	{
    	case ASN1_ETYPE_ANY:
    	  if ((p->type & CONST_DEFINED_BY) && (p->value))
    	    {
    	      /* search the "DEF_BY" element */
    	      p2 = p->down;
    	      while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT))
    		p2 = p2->right;

    	      if (!p2)
    		{
    		  retCode = ASN1_ERROR_TYPE_ANY;
    		  break;
    		}

    	      p3 = _asn1_find_up (p);

    	      if (!p3)
    		{
    		  retCode = ASN1_ERROR_TYPE_ANY;
    		  break;
    		}

    	      p3 = p3->down;
    	      while (p3)
    		{
    		  if (!(strcmp (p3->name, p2->name)))
    		    break;
    		  p3 = p3->right;
    		}

    	      if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
    		  (p3->value == NULL))
    		{

    		  p3 = _asn1_find_up (p);
    		  p3 = _asn1_find_up (p3);

    		  if (!p3)
    		    {
    		      retCode = ASN1_ERROR_TYPE_ANY;
    		      break;
    		    }

    		  p3 = p3->down;

    		  while (p3)
    		    {
    		      if (!(strcmp (p3->name, p2->name)))
    			break;
    		      p3 = p3->right;
    		    }

    		  if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
    		      || (p3->value == NULL))
    		    {
    		      retCode = ASN1_ERROR_TYPE_ANY;
    		      break;
    		    }
    		}

    	      /* search the OBJECT_ID into definitions */
    	      p2 = definitions->down;
    	      while (p2)
    		{
    		  if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
    		      (p2->type & CONST_ASSIGN))
    		    {
    		      strcpy (name, definitionsName);
    		      strcat (name, p2->name);

    		      len = ASN1_MAX_NAME_SIZE;
    		      result =
    			asn1_read_value (definitions, name, value, &len);

    		      if ((result == ASN1_SUCCESS)
    			  && (!_asn1_strcmp (p3->value, value)))
    			{
    			  p2 = p2->right;	/* pointer to the structure to
    						   use for expansion */
    			  while ((p2) && (p2->type & CONST_ASSIGN))
    			    p2 = p2->right;

    			  if (p2)
    			    {
    			      strcpy (name, definitionsName);
    			      strcat (name, p2->name);

    			      result =
    				asn1_create_element (definitions, name, &aux);
    			      if (result == ASN1_SUCCESS)
    				{
    				  _asn1_cpy_name (aux, p);
    				  len2 =
    				    asn1_get_length_der (p->value,
    							 p->value_len, &len3);
    				  if (len2 < 0)
    				    return ASN1_DER_ERROR;

    				  result =
    				    asn1_der_decoding (&aux, p->value + len3,
    						       len2,
    						       errorDescription);
    				  if (result == ASN1_SUCCESS)
    				    {

    				      _asn1_set_right (aux, p->right);
    				      _asn1_set_right (p, aux);

    				      result = asn1_delete_structure (&p);
    				      if (result == ASN1_SUCCESS)
    					{
    					  p = aux;
    					  aux = NULL;
    					  break;
    					}
    				      else
    					{	/* error with asn1_delete_structure */
    					  asn1_delete_structure (&aux);
    					  retCode = result;
    					  break;
    					}
    				    }
    				  else
    				    {	/* error with asn1_der_decoding */
    				      retCode = result;
    				      break;
    				    }
    				}
    			      else
    				{	/* error with asn1_create_element */
    				  retCode = result;
    				  break;
    				}
    			    }
    			  else
    			    {	/* error with the pointer to the structure to exapand */
    			      retCode = ASN1_ERROR_TYPE_ANY;
    			      break;
    			    }
    			}
    		    }
    		  p2 = p2->right;
    		}		/* end while */

    	      if (!p2)
    		{
    		  retCode = ASN1_ERROR_TYPE_ANY;
    		  break;
    		}

    	    }
    	  break;
    	default:
    	  break;
    	}

          if (p->down)
    	{
    	  p = p->down;
    	}
          else if (p == *element)
    	{
    	  p = NULL;
    	  break;
    	}
          else if (p->right)
    	p = p->right;
          else
    	{
    	  while (1)
    	    {
    	      p = _asn1_find_up (p);
    	      if (p == *element)
    		{
    		  p = NULL;
    		  break;
    		}
    	      if (p->right)
    		{
    		  p = p->right;
    		  break;
    		}
    	    }
    	}
        }

      return retCode;
    }
↓ | _asn1_extract_tag_der | 40 | 76 | 171 | decoding.c
    static int
    _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
    		       int *ret_len)
    {
      asn1_node p;
      int counter, len2, len3, is_tag_implicit;
      unsigned long tag, tag_implicit = 0;
      unsigned char class, class2, class_implicit = 0;

      if (der_len <= 0)
        return ASN1_GENERIC_ERROR;

      counter = is_tag_implicit = 0;

      if (node->type & CONST_TAG)
        {
          p = node->down;
          while (p)
    	{
    	  if (type_field (p->type) == ASN1_ETYPE_TAG)
    	    {
    	      if (p->type & CONST_APPLICATION)
    		class2 = ASN1_CLASS_APPLICATION;
    	      else if (p->type & CONST_UNIVERSAL)
    		class2 = ASN1_CLASS_UNIVERSAL;
    	      else if (p->type & CONST_PRIVATE)
    		class2 = ASN1_CLASS_PRIVATE;
    	      else
    		class2 = ASN1_CLASS_CONTEXT_SPECIFIC;

    	      if (p->type & CONST_EXPLICIT)
    		{
    		  if (asn1_get_tag_der
    		      (der + counter, der_len - counter, &class, &len2,
    		       &tag) != ASN1_SUCCESS)
    		    return ASN1_DER_ERROR;

    		  if (counter + len2 > der_len)
    		    return ASN1_DER_ERROR;
    		  counter += len2;

    		  len3 =
    		    asn1_get_length_ber (der + counter, der_len - counter,
    					 &len2);
    		  if (len3 < 0)
    		    return ASN1_DER_ERROR;

    		  counter += len2;
    		  if (counter > der_len)
    		    return ASN1_DER_ERROR;

    		  if (!is_tag_implicit)
    		    {
    		      if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
    			  (tag != strtoul ((char *) p->value, NULL, 10)))
    			return ASN1_TAG_ERROR;
    		    }
    		  else
    		    {		/* ASN1_TAG_IMPLICIT */
    		      if ((class != class_implicit) || (tag != tag_implicit))
    			return ASN1_TAG_ERROR;
    		    }
    		  is_tag_implicit = 0;
    		}
    	      else
    		{		/* ASN1_TAG_IMPLICIT */
    		  if (!is_tag_implicit)
    		    {
    		      if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
    			  (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
    			  || (type_field (node->type) == ASN1_ETYPE_SET)
    			  || (type_field (node->type) == ASN1_ETYPE_SET_OF))
    			class2 |= ASN1_CLASS_STRUCTURED;
    		      class_implicit = class2;
    		      tag_implicit = strtoul ((char *) p->value, NULL, 10);
    		      is_tag_implicit = 1;
    		    }
    		}
    	    }
    	  p = p->right;
    	}
        }

      if (is_tag_implicit)
        {
          if (asn1_get_tag_der
    	  (der + counter, der_len - counter, &class, &len2,
    	   &tag) != ASN1_SUCCESS)
    	return ASN1_DER_ERROR;
          if (counter + len2 > der_len)
    	return ASN1_DER_ERROR;

          if ((class != class_implicit) || (tag != tag_implicit))
    	{
    	  if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING)
    	    {
    	      class_implicit |= ASN1_CLASS_STRUCTURED;
    	      if ((class != class_implicit) || (tag != tag_implicit))
    		return ASN1_TAG_ERROR;
    	    }
    	  else
    	    return ASN1_TAG_ERROR;
    	}
        }
      else
        {
          unsigned type = type_field (node->type);
          if (type == ASN1_ETYPE_TAG)
    	{
    	  counter = 0;
    	  *ret_len = counter;
    	  return ASN1_SUCCESS;
    	}

          if (asn1_get_tag_der
    	  (der + counter, der_len - counter, &class, &len2,
    	   &tag) != ASN1_SUCCESS)
    	return ASN1_DER_ERROR;

          if (counter + len2 > der_len)
    	return ASN1_DER_ERROR;

          switch (type)
    	{
    	case ASN1_ETYPE_NULL:
    	case ASN1_ETYPE_BOOLEAN:
    	case ASN1_ETYPE_INTEGER:
    	case ASN1_ETYPE_ENUMERATED:
    	case ASN1_ETYPE_OBJECT_ID:
    	case ASN1_ETYPE_GENERALSTRING:
    	case ASN1_ETYPE_NUMERIC_STRING:
    	case ASN1_ETYPE_IA5_STRING:
    	case ASN1_ETYPE_TELETEX_STRING:
    	case ASN1_ETYPE_PRINTABLE_STRING:
    	case ASN1_ETYPE_UNIVERSAL_STRING:
    	case ASN1_ETYPE_BMP_STRING:
    	case ASN1_ETYPE_UTF8_STRING:
    	case ASN1_ETYPE_VISIBLE_STRING:
    	case ASN1_ETYPE_BIT_STRING:
    	case ASN1_ETYPE_SEQUENCE:
    	case ASN1_ETYPE_SEQUENCE_OF:
    	case ASN1_ETYPE_SET:
    	case ASN1_ETYPE_SET_OF:
    	case ASN1_ETYPE_GENERALIZED_TIME:
    	case ASN1_ETYPE_UTC_TIME:
    	  if ((class != _asn1_tags[type].class)
    	      || (tag != _asn1_tags[type].tag))
    	    return ASN1_DER_ERROR;
    	  break;

    	case ASN1_ETYPE_OCTET_STRING:
    	  /* OCTET STRING is handled differently to allow
    	   * BER encodings (structured class). */
    	  if (((class != ASN1_CLASS_UNIVERSAL)
    	       && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
    	      || (tag != ASN1_TAG_OCTET_STRING))
    	    return ASN1_DER_ERROR;
    	  break;
    	case ASN1_ETYPE_ANY:
    	  counter -= len2;
    	  break;
    	default:
    	  return ASN1_DER_ERROR;
    	  break;
    	}
        }

      counter += len2;
      *ret_len = counter;
      return ASN1_SUCCESS;
    }
↓ | asn1_read_value_type | 36 | 83 | 170 | element.c
    int
    asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
    		      int *len, unsigned int *etype)
    {
      asn1_node node, p, p2;
      int len2, len3;
      int value_size = *len;
      unsigned char *value = ivalue;
      unsigned type;

      node = asn1_find_node (root, name);
      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      type = type_field (node->type);

      if ((type != ASN1_ETYPE_NULL) &&
          (type != ASN1_ETYPE_CHOICE) &&
          !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
          (node->value == NULL))
        return ASN1_VALUE_NOT_FOUND;

      if (etype)
        *etype = type;
      switch (type)
        {
        case ASN1_ETYPE_NULL:
          PUT_STR_VALUE (value, value_size, "NULL");
          break;
        case ASN1_ETYPE_BOOLEAN:
          if ((node->type & CONST_DEFAULT) && (node->value == NULL))
    	{
    	  p = node->down;
    	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
    	    p = p->right;
    	  if (p->type & CONST_TRUE)
    	    {
    	      PUT_STR_VALUE (value, value_size, "TRUE");
    	    }
    	  else
    	    {
    	      PUT_STR_VALUE (value, value_size, "FALSE");
    	    }
    	}
          else if (node->value[0] == 'T')
    	{
    	  PUT_STR_VALUE (value, value_size, "TRUE");
    	}
          else
    	{
    	  PUT_STR_VALUE (value, value_size, "FALSE");
    	}
          break;
        case ASN1_ETYPE_INTEGER:
        case ASN1_ETYPE_ENUMERATED:
          if ((node->type & CONST_DEFAULT) && (node->value == NULL))
    	{
    	  p = node->down;
    	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
    	    p = p->right;
    	  if ((isdigit (p->value[0])) || (p->value[0] == '-')
    	      || (p->value[0] == '+'))
    	    {
    	      if (_asn1_convert_integer
    		  (p->value, value, value_size, len) != ASN1_SUCCESS)
    		return ASN1_MEM_ERROR;
    	    }
    	  else
    	    {			/* is an identifier like v1 */
    	      p2 = node->down;
    	      while (p2)
    		{
    		  if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
    		    {
    		      if (!_asn1_strcmp (p2->name, p->value))
    			{
    			  if (_asn1_convert_integer
    			      (p2->value, value, value_size,
    			       len) != ASN1_SUCCESS)
    			    return ASN1_MEM_ERROR;
    			  break;
    			}
    		    }
    		  p2 = p2->right;
    		}
    	    }
    	}
          else
    	{
    	  len2 = -1;
    	  if (asn1_get_octet_der
    	      (node->value, node->value_len, &len2, value, value_size,
    	       len) != ASN1_SUCCESS)
    	    return ASN1_MEM_ERROR;
    	}
          break;
        case ASN1_ETYPE_OBJECT_ID:
          if (node->type & CONST_ASSIGN)
    	{
    	  value[0] = 0;
    	  p = node->down;
    	  while (p)
    	    {
    	      if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
    		{
    		  ADD_STR_VALUE (value, value_size, p->value);
    		  if (p->right)
    		    {
    		      ADD_STR_VALUE (value, value_size, ".");
    		    }
    		}
    	      p = p->right;
    	    }
    	  *len = _asn1_strlen (value) + 1;
    	}
          else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
    	{
    	  p = node->down;
    	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
    	    p = p->right;
    	  PUT_STR_VALUE (value, value_size, p->value);
    	}
          else
    	{
    	  PUT_STR_VALUE (value, value_size, node->value);
    	}
          break;
        case ASN1_ETYPE_GENERALIZED_TIME:
        case ASN1_ETYPE_UTC_TIME:
          PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len);
          break;
        case ASN1_ETYPE_OCTET_STRING:
        case ASN1_ETYPE_GENERALSTRING:
        case ASN1_ETYPE_NUMERIC_STRING:
        case ASN1_ETYPE_IA5_STRING:
        case ASN1_ETYPE_TELETEX_STRING:
        case ASN1_ETYPE_PRINTABLE_STRING:
        case ASN1_ETYPE_UNIVERSAL_STRING:
        case ASN1_ETYPE_BMP_STRING:
        case ASN1_ETYPE_UTF8_STRING:
        case ASN1_ETYPE_VISIBLE_STRING:
          len2 = -1;
          if (asn1_get_octet_der
    	  (node->value, node->value_len, &len2, value, value_size,
    	   len) != ASN1_SUCCESS)
    	return ASN1_MEM_ERROR;
          break;
        case ASN1_ETYPE_BIT_STRING:
          len2 = -1;
          if (asn1_get_bit_der
    	  (node->value, node->value_len, &len2, value, value_size,
    	   len) != ASN1_SUCCESS)
    	return ASN1_MEM_ERROR;
          break;
        case ASN1_ETYPE_CHOICE:
          PUT_STR_VALUE (value, value_size, node->down->name);
          break;
        case ASN1_ETYPE_ANY:
          len3 = -1;
          len2 = asn1_get_length_der (node->value, node->value_len, &len3);
          if (len2 < 0)
    	return ASN1_DER_ERROR;
          PUT_VALUE (value, value_size, node->value + len3, len2);
          break;
        default:
          return ASN1_ELEMENT_NOT_FOUND;
          break;
        }
      return ASN1_SUCCESS;
    }
↓ | _asn1_check_identifier | 27 | 52 | 94 | parser_aux.c
    int
    _asn1_check_identifier (asn1_node node)
    {
      asn1_node p, p2;
      char name2[ASN1_MAX_NAME_SIZE * 2 + 2];

      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      p = node;
      while (p)
        {
          if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
    	{
    	  _asn1_str_cpy (name2, sizeof (name2), node->name);
    	  _asn1_str_cat (name2, sizeof (name2), ".");
    	  _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
    	  p2 = asn1_find_node (node, name2);
    	  if (p2 == NULL)
    	    {
    	      if (p->value)
    		_asn1_strcpy (_asn1_identifierMissing, p->value);
    	      else
    		_asn1_strcpy (_asn1_identifierMissing, "(null)");
    	      return ASN1_IDENTIFIER_NOT_FOUND;
    	    }
    	}
          else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
    	       (p->type & CONST_DEFAULT))
    	{
    	  p2 = p->down;
    	  if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
    	    {
    	      _asn1_str_cpy (name2, sizeof (name2), node->name);
    	      _asn1_str_cat (name2, sizeof (name2), ".");
    	      _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
    	      _asn1_strcpy (_asn1_identifierMissing, p2->value);
    	      p2 = asn1_find_node (node, name2);
    	      if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
    		  !(p2->type & CONST_ASSIGN))
    		return ASN1_IDENTIFIER_NOT_FOUND;
    	      else
    		_asn1_identifierMissing[0] = 0;
    	    }
    	}
          else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
    	       (p->type & CONST_ASSIGN))
    	{
    	  p2 = p->down;
    	  if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
    	    {
    	      if (p2->value && !isdigit (p2->value[0]))
    		{
    		  _asn1_str_cpy (name2, sizeof (name2), node->name);
    		  _asn1_str_cat (name2, sizeof (name2), ".");
    		  _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
    		  _asn1_strcpy (_asn1_identifierMissing, p2->value);
    		  p2 = asn1_find_node (node, name2);
    		  if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID)
    		      || !(p2->type & CONST_ASSIGN))
    		    return ASN1_IDENTIFIER_NOT_FOUND;
    		  else
    		    _asn1_identifierMissing[0] = 0;
    		}
    	    }
    	}

          if (p->down)
    	{
    	  p = p->down;
    	}
          else if (p->right)
    	p = p->right;
          else
    	{
    	  while (1)
    	    {
    	      p = _asn1_find_up (p);
    	      if (p == node)
    		{
    		  p = NULL;
    		  break;
    		}
    	      if (p->right)
    		{
    		  p = p->right;
    		  break;
    		}
    	    }
    	}
        }

      return ASN1_SUCCESS;
    }
↓ | _asn1_expand_identifier | 25 | 66 | 105 | structure.c
    static int
    _asn1_expand_identifier (asn1_node * node, asn1_node root)
    {
      asn1_node 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) == ASN1_ETYPE_IDENTIFIER)
    	    {
    	      snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value);
    	      p2 = _asn1_copy_structure2 (root, name2);
    	      if (p2 == NULL)
    		{
    		  return ASN1_IDENTIFIER_NOT_FOUND;
    		}
    	      _asn1_cpy_name (p2, p);
    	      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;
    }
↓ | _asn1_ordering_set_of | 23 | 72 | 124 | coding.c
    static void
    _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
    {
      struct vet
      {
        int end;
        struct vet *next, *prev;
      };

      int counter, len, len2, change;
      struct vet *first, *last, *p_vet, *p2_vet;
      asn1_node p;
      unsigned char *temp, class;
      unsigned long k, max;

      counter = 0;

      if (type_field (node->type) != ASN1_ETYPE_SET_OF)
        return;

      p = node->down;
      while ((type_field (p->type) == ASN1_ETYPE_TAG)
    	 || (type_field (p->type) == ASN1_ETYPE_SIZE))
        p = p->right;
      p = p->right;

      if ((p == NULL) || (p->right == NULL))
        return;

      first = last = NULL;
      while (p)
        {
          p_vet = malloc (sizeof (struct vet));
          if (p_vet == NULL)
    	return;

          p_vet->next = NULL;
          p_vet->prev = last;
          if (first == NULL)
    	first = p_vet;
          else
    	last->next = p_vet;
          last = p_vet;

          /* extraction of tag and length */
          if (der_len - counter > 0)
    	{

    	  if (asn1_get_tag_der
    	      (der + counter, der_len - counter, &class, &len,
    	       NULL) != ASN1_SUCCESS)
    	    return;
    	  counter += len;

    	  len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
    	  if (len2 < 0)
    	    return;
    	  counter += len + len2;
    	}

          p_vet->end = counter;
          p = p->right;
        }

      p_vet = first;

      while (p_vet)
        {
          p2_vet = p_vet->next;
          counter = 0;
          while (p2_vet)
    	{
    	  if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
    	    max = p_vet->end - counter;
    	  else
    	    max = p2_vet->end - p_vet->end;

    	  change = -1;
    	  for (k = 0; k < max; k++)
    	    if (der[counter + k] > der[p_vet->end + k])
    	      {
    		change = 1;
    		break;
    	      }
    	    else if (der[counter + k] < der[p_vet->end + k])
    	      {
    		change = 0;
    		break;
    	      }

    	  if ((change == -1)
    	      && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
    	    change = 1;

    	  if (change == 1)
    	    {
    	      /* change position */
    	      temp = malloc (p_vet->end - counter);
    	      if (temp == NULL)
    		return;

    	      memcpy (temp, der + counter, (p_vet->end) - counter);
    	      memcpy (der + counter, der + (p_vet->end),
    		      (p2_vet->end) - (p_vet->end));
    	      memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
    		      (p_vet->end) - counter);
    	      free (temp);

    	      p_vet->end = counter + (p2_vet->end - p_vet->end);
    	    }
    	  counter = p_vet->end;

    	  p2_vet = p2_vet->next;
    	  p_vet = p_vet->next;
    	}

          if (p_vet != first)
    	p_vet->prev->next = NULL;
          else
    	first = NULL;
          free (p_vet);
          p_vet = first;
        }
    }
↓ | asn1_expand_octet_string | 22 | 65 | 123 | decoding.c
    int
    asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
    			  const char *octetName, const char *objectName)
    {
      char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
      int retCode = ASN1_SUCCESS, result;
      int len, len2, len3;
      asn1_node p2, aux = NULL;
      asn1_node octetNode = NULL, objectNode = NULL;
      char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];

      if ((definitions == NULL) || (*element == NULL))
        return ASN1_ELEMENT_NOT_FOUND;

      octetNode = asn1_find_node (*element, octetName);
      if (octetNode == NULL)
        return ASN1_ELEMENT_NOT_FOUND;
      if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
        return ASN1_ELEMENT_NOT_FOUND;
      if (octetNode->value == NULL)
        return ASN1_VALUE_NOT_FOUND;

      objectNode = asn1_find_node (*element, objectName);
      if (objectNode == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID)
        return ASN1_ELEMENT_NOT_FOUND;

      if (objectNode->value == NULL)
        return ASN1_VALUE_NOT_FOUND;

      /* search the OBJECT_ID into definitions */
      p2 = definitions->down;
      while (p2)
        {
          if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
    	  (p2->type & CONST_ASSIGN))
    	{
    	  strcpy (name, definitions->name);
    	  strcat (name, ".");
    	  strcat (name, p2->name);

    	  len = sizeof (value);
    	  result = asn1_read_value (definitions, name, value, &len);

    	  if ((result == ASN1_SUCCESS)
    	      && (!_asn1_strcmp (objectNode->value, value)))
    	    {

    	      p2 = p2->right;	/* pointer to the structure to
    				   use for expansion */
    	      while ((p2) && (p2->type & CONST_ASSIGN))
    		p2 = p2->right;

    	      if (p2)
    		{
    		  strcpy (name, definitions->name);
    		  strcat (name, ".");
    		  strcat (name, p2->name);

    		  result = asn1_create_element (definitions, name, &aux);
    		  if (result == ASN1_SUCCESS)
    		    {
    		      _asn1_cpy_name (aux, octetNode);
    		      len2 =
    			asn1_get_length_der (octetNode->value,
    					     octetNode->value_len, &len3);
    		      if (len2 < 0)
    			return ASN1_DER_ERROR;

    		      result =
    			asn1_der_decoding (&aux, octetNode->value + len3,
    					   len2, errorDescription);
    		      if (result == ASN1_SUCCESS)
    			{

    			  _asn1_set_right (aux, octetNode->right);
    			  _asn1_set_right (octetNode, aux);

    			  result = asn1_delete_structure (&octetNode);
    			  if (result == ASN1_SUCCESS)
    			    {
    			      aux = NULL;
    			      break;
    			    }
    			  else
    			    {	/* error with asn1_delete_structure */
    			      asn1_delete_structure (&aux);
    			      retCode = result;
    			      break;
    			    }
    			}
    		      else
    			{	/* error with asn1_der_decoding */
    			  retCode = result;
    			  break;
    			}
    		    }
    		  else
    		    {		/* error with asn1_create_element */
    		      retCode = result;
    		      break;
    		    }
    		}
    	      else
    		{		/* error with the pointer to the structure to exapand */
    		  retCode = ASN1_VALUE_NOT_VALID;
    		  break;
    		}
    	    }
    	}

          p2 = p2->right;

        }

      if (!p2)
        retCode = ASN1_VALUE_NOT_VALID;

      return retCode;
    }
↓ | yysyntax_error | 22 | 54 | 127 | ASN1.c
    static int
    yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                    yytype_int16 *yyssp, int yytoken)
    {
      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
      YYSIZE_T yysize = yysize0;
      YYSIZE_T yysize1;
      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
      /* Internationalized format string. */
      const char *yyformat = 0;
      /* Arguments of yyformat. */
      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
      /* Number of reported tokens (one for the "unexpected", one per
         "expected"). */
      int yycount = 0;

      /* There are many possibilities here to consider:
         - Assume YYFAIL is not used.  It's too flawed to consider.  See

           for details.  YYERROR is fine as it does not invoke this
           function.
         - If this state is a consistent state with a default action, then
           the only way this function was invoked is if the default action
           is an error action.  In that case, don't check for expected
           tokens because there are none.
         - The only way there can be no lookahead present (in yychar) is if
           this state is a consistent state with a default action.  Thus,
           detecting the absence of a lookahead is sufficient to determine
           that there is no unexpected or expected token to report.  In that
           case, just report a simple "syntax error".
         - Don't assume there isn't a lookahead just because this state is a
           consistent state with a default action.  There might have been a
           previous inconsistent state, consistent state with a non-default
           action, or user semantic action that manipulated yychar.
         - Of course, the expected token list depends on states to have
           correct lookahead information, and it depends on the parser not
           to perform extra reductions after fetching a lookahead from the
           scanner and before detecting a syntax error.  Thus, state merging
           (from LALR or IELR) and default reductions corrupt the expected
           token list.  However, the list is correct for canonical LR with
           one exception: it will still contain any token that will not be
           accepted due to an error action in a later state.
      */
      if (yytoken != YYEMPTY)
        {
          int yyn = yypact[*yyssp];
          yyarg[yycount++] = yytname[yytoken];
          if (!yypact_value_is_default (yyn))
            {
              /* Start YYX at -YYN if negative to avoid negative indexes in
                 YYCHECK.  In other words, skip the first -YYN actions for
                 this state because they are default actions.  */
              int yyxbegin = yyn < 0 ? -yyn : 0;
              /* Stay within bounds of both yycheck and yytname.  */
              int yychecklim = YYLAST - yyn + 1;
              int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
              int yyx;

              for (yyx = yyxbegin; yyx < yyxend; ++yyx)
                if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
                    && !yytable_value_is_error (yytable[yyx + yyn]))
                  {
                    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
                      {
                        yycount = 1;
                        yysize = yysize0;
                        break;
                      }
                    yyarg[yycount++] = yytname[yyx];
                    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
                    if (! (yysize <= yysize1
                           && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
                      return 2;
                    yysize = yysize1;
                  }
            }
        }

      switch (yycount)
        {
    # define YYCASE_(N, S)                      \
          case N:                               \
            yyformat = S;                       \
          break
          YYCASE_(0, YY_("syntax error"));
          YYCASE_(1, YY_("syntax error, unexpected %s"));
          YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
          YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
          YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
          YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
    # undef YYCASE_
        }

      yysize1 = yysize + yystrlen (yyformat);
      if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
        return 2;
      yysize = yysize1;

      if (*yymsg_alloc < yysize)
        {
          *yymsg_alloc = 2 * yysize;
          if (! (yysize <= *yymsg_alloc
                 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
            *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
          return 1;
        }

      /* Avoid sprintf, as that infringes on the user's name space.
         Don't have undefined behavior even if the translation
         produced a string with the wrong number of "%s"s.  */
      {
        char *yyp = *yymsg;
        int yyi = 0;
        while ((*yyp = *yyformat) != '\0')
          if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
            {
              yyp += yytnamerr (yyp, yyarg[yyi++]);
              yyformat += 2;
            }
          else
            {
              yyp++;
              yyformat++;
            }
      }
      return 0;
    }
↓ | asn1_find_node | 21 | 58 | 106 | parser_aux.c
    asn1_node
    asn1_find_node (asn1_node pointer, const char *name)
    {
      asn1_node p;
      char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
      const char *n_start;
      unsigned int nsize;
      unsigned int nhash;

      if (pointer == NULL)
        return NULL;

      if (name == NULL)
        return NULL;

      p = pointer;
      n_start = name;

      if (p->name[0] != 0)
        {				/* has *pointer got a name ? */
          n_end = strchr (n_start, '.');	/* search the first dot */
          if (n_end)
    	{
    	  nsize = n_end - n_start;
    	  memcpy (n, n_start, nsize);
    	  n[nsize] = 0;
    	  n_start = n_end;
    	  n_start++;

    	  nhash = hash_pjw_bare (n, nsize);
    	}
          else
    	{
    	  nsize = _asn1_str_cpy (n, sizeof (n), n_start);
    	  nhash = hash_pjw_bare (n, nsize);

    	  n_start = NULL;
    	}

          while (p)
    	{
    	  if ((p->name) && nhash == p->name_hash && (!strcmp (p->name, n)))
    	    break;
    	  else
    	    p = p->right;
    	}			/* while */

          if (p == NULL)
    	return NULL;
        }
      else
        {				/* *pointer doesn't have a name */
          if (n_start[0] == 0)
    	return p;
        }

      while (n_start)
        {				/* Has the end of NAME been reached? */
          n_end = strchr (n_start, '.');	/* search the next dot */
          if (n_end)
    	{
    	  nsize = n_end - n_start;
    	  memcpy (n, n_start, nsize);
    	  n[nsize] = 0;
    	  n_start = n_end;
    	  n_start++;

    	  nhash = hash_pjw_bare (n, nsize);
    	}
          else
    	{
    	  nsize = _asn1_str_cpy (n, sizeof (n), n_start);
    	  nhash = hash_pjw_bare (n, nsize);
    	  n_start = NULL;
    	}

          if (p->down == NULL)
    	return NULL;

          p = p->down;

          /* The identifier "?LAST" indicates the last element
             in the right chain. */
          if (!strcmp (n, "?LAST"))
    	{
    	  if (p == NULL)
    	    return NULL;
    	  while (p->right)
    	    p = p->right;
    	}
          else
    	{			/* no "?LAST" */
    	  while (p)
    	    {
    	      if (p->name_hash == nhash && !strcmp (p->name, n))
    		break;
    	      else
    		p = p->right;
    	    }
    	  if (p == NULL)
    	    return NULL;
    	}
        }				/* while */

      return p;
    }
↓ | asn1_array2tree | 21 | 55 | 100 | structure.c
    int
    asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
    		 char *errorDescription)
    {
      asn1_node p, p_last = NULL;
      unsigned long k;
      int move;
      int result;
      unsigned int type;

      if (*definitions != NULL)
        return ASN1_ELEMENT_NOT_EMPTY;

      move = UP;

      k = 0;
      while (array[k].value || array[k].type || array[k].name)
        {
          type = convert_old_type (array[k].type);

          p = _asn1_add_static_node (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 (type & CONST_DOWN)
    	move = DOWN;
          else if (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 = NULL;
        }
      else
        _asn1_delete_list ();

      return result;
    }
↓ | _asn1_type_choice_config | 20 | 47 | 84 | structure.c
    static int
    _asn1_type_choice_config (asn1_node node)
    {
      asn1_node p, p2, p3, p4;
      int move, tlen;

      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) == ASN1_ETYPE_CHOICE)
    	      && (p->type & CONST_TAG))
    	    {
    	      p2 = p->down;
    	      while (p2)
    		{
    		  if (type_field (p2->type) != ASN1_ETYPE_TAG)
    		    {
    		      p2->type |= CONST_TAG;
    		      p3 = _asn1_find_left (p2);
    		      while (p3)
    			{
    			  if (type_field (p3->type) == ASN1_ETYPE_TAG)
    			    {
    			      p4 = _asn1_add_single_node (p3->type);
    			      tlen = _asn1_strlen (p3->value);
    			      if (tlen > 0)
    				_asn1_set_value (p4, p3->value, tlen + 1);
    			      _asn1_set_right (p4, p2->down);
    			      _asn1_set_down (p2, p4);
    			    }
    			  p3 = _asn1_find_left (p3);
    			}
    		    }
    		  p2 = p2->right;
    		}
    	      p->type &= ~(CONST_TAG);
    	      p2 = p->down;
    	      while (p2)
    		{
    		  p3 = p2->right;
    		  if (type_field (p2->type) == ASN1_ETYPE_TAG)
    		    asn1_delete_structure (&p2);
    		  p2 = p3;
    		}
    	    }
    	  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;
    }
↓ | _asn1_insert_tag_der | 19 | 50 | 100 | coding.c
    static int
    _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
    		      int *max_len)
    {
      asn1_node p;
      int tag_len, is_tag_implicit;
      unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
      unsigned long tag_implicit = 0;
      unsigned char tag_der[MAX_TAG_LEN];

      is_tag_implicit = 0;

      if (node->type & CONST_TAG)
        {
          p = node->down;
          while (p)
    	{
    	  if (type_field (p->type) == ASN1_ETYPE_TAG)
    	    {
    	      if (p->type & CONST_APPLICATION)
    		class = ASN1_CLASS_APPLICATION;
    	      else if (p->type & CONST_UNIVERSAL)
    		class = ASN1_CLASS_UNIVERSAL;
    	      else if (p->type & CONST_PRIVATE)
    		class = ASN1_CLASS_PRIVATE;
    	      else
    		class = ASN1_CLASS_CONTEXT_SPECIFIC;

    	      if (p->type & CONST_EXPLICIT)
    		{
    		  if (is_tag_implicit)
    		    _asn1_tag_der (class_implicit, tag_implicit, tag_der,
    				   &tag_len);
    		  else
    		    _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
    				   _asn1_strtoul (p->value, NULL, 10),
    				   tag_der, &tag_len);

    		  *max_len -= tag_len;
    		  if (*max_len >= 0)
    		    memcpy (der + *counter, tag_der, tag_len);
    		  *counter += tag_len;

    		  _asn1_ltostr (*counter, (char *) temp);
    		  _asn1_set_name (p, (const char *) temp);

    		  is_tag_implicit = 0;
    		}
    	      else
    		{		/* CONST_IMPLICIT */
    		  if (!is_tag_implicit)
    		    {
    		      if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
    			  (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
    			  || (type_field (node->type) == ASN1_ETYPE_SET)
    			  || (type_field (node->type) == ASN1_ETYPE_SET_OF))
    			class |= ASN1_CLASS_STRUCTURED;
    		      class_implicit = class;
    		      tag_implicit = _asn1_strtoul (p->value, NULL, 10);
    		      is_tag_implicit = 1;
    		    }
    		}
    	    }
    	  p = p->right;
    	}
        }

      if (is_tag_implicit)
        {
          _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
        }
      else
        {
          unsigned type = type_field (node->type);
          switch (type)
    	{
    	CASE_HANDLED_ETYPES:
    	  _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
    			 tag_der, &tag_len);
    	  break;
    	case ASN1_ETYPE_TAG:
    	case ASN1_ETYPE_CHOICE:
    	case ASN1_ETYPE_ANY:
    	  tag_len = 0;
    	  break;
    	default:
    	  return ASN1_GENERIC_ERROR;
    	}
        }

      *max_len -= tag_len;
      if (*max_len >= 0)
        memcpy (der + *counter, tag_der, tag_len);
      *counter += tag_len;

      if (*max_len < 0)
        return ASN1_MEM_ERROR;

      return ASN1_SUCCESS;
    }
↓ | _asn1_ordering_set | 16 | 59 | 104 | coding.c
    static void
    _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node)
    {
      struct vet
      {
        int end;
        unsigned long value;
        struct vet *next, *prev;
      };

      int counter, len, len2;
      struct vet *first, *last, *p_vet, *p2_vet;
      asn1_node p;
      unsigned char class, *temp;
      unsigned long tag;

      counter = 0;

      if (type_field (node->type) != ASN1_ETYPE_SET)
        return;

      p = node->down;
      while ((type_field (p->type) == ASN1_ETYPE_TAG)
    	 || (type_field (p->type) == ASN1_ETYPE_SIZE))
        p = p->right;

      if ((p == NULL) || (p->right == NULL))
        return;

      first = last = NULL;
      while (p)
        {
          p_vet = malloc (sizeof (struct vet));
          if (p_vet == NULL)
    	return;

          p_vet->next = NULL;
          p_vet->prev = last;
          if (first == NULL)
    	first = p_vet;
          else
    	last->next = p_vet;
          last = p_vet;

          /* tag value calculation */
          if (asn1_get_tag_der
    	  (der + counter, der_len - counter, &class, &len2,
    	   &tag) != ASN1_SUCCESS)
    	return;
          p_vet->value = (class << 24) | tag;
          counter += len2;

          /* extraction and length */
          len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
          if (len2 < 0)
    	return;
          counter += len + len2;

          p_vet->end = counter;
          p = p->right;
        }

      p_vet = first;

      while (p_vet)
        {
          p2_vet = p_vet->next;
          counter = 0;
          while (p2_vet)
    	{
    	  if (p_vet->value > p2_vet->value)
    	    {
    	      /* change position */
    	      temp = malloc (p_vet->end - counter);
    	      if (temp == NULL)
    		return;

    	      memcpy (temp, der + counter, p_vet->end - counter);
    	      memcpy (der + counter, der + p_vet->end,
    		      p2_vet->end - p_vet->end);
    	      memcpy (der + counter + p2_vet->end - p_vet->end, temp,
    		      p_vet->end - counter);
    	      free (temp);

    	      tag = p_vet->value;
    	      p_vet->value = p2_vet->value;
    	      p2_vet->value = tag;

    	      p_vet->end = counter + (p2_vet->end - p_vet->end);
    	    }
    	  counter = p_vet->end;

    	  p2_vet = p2_vet->next;
    	  p_vet = p_vet->next;
    	}

          if (p_vet != first)
    	p_vet->prev->next = NULL;
          else
    	first = NULL;
          free (p_vet);
          p_vet = first;
        }
    }
↓ | _asn1_get_octet_string | 16 | 44 | 79 | decoding.c
    static int
    _asn1_get_octet_string (const unsigned char *der, asn1_node node, int *len)
    {
      int len2, len3, counter, tot_len, indefinite;

      counter = 0;

      if (*(der - 1) & ASN1_CLASS_STRUCTURED)
        {
          tot_len = 0;
          indefinite = asn1_get_length_der (der, *len, &len3);
          if (indefinite < -1)
    	return ASN1_DER_ERROR;

          counter += len3;
          if (indefinite >= 0)
    	indefinite += len3;

          while (1)
    	{
    	  if (counter > (*len))
    	    return ASN1_DER_ERROR;

    	  if (indefinite == -1)
    	    {
    	      if ((der[counter] == 0) && (der[counter + 1] == 0))
    		{
    		  counter += 2;
    		  break;
    		}
    	    }
    	  else if (counter >= indefinite)
    	    break;

    	  if (der[counter] != ASN1_TAG_OCTET_STRING)
    	    return ASN1_DER_ERROR;

    	  counter++;

    	  len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
    	  if (len2 <= 0)
    	    return ASN1_DER_ERROR;

    	  counter += len3 + len2;
    	  tot_len += len2;
    	}

          /* copy */
          if (node)
    	{
    	  unsigned char temp[DER_LEN];
    	  int ret;

    	  len2 = sizeof (temp);

    	  asn1_length_der (tot_len, temp, &len2);
    	  _asn1_set_value (node, temp, len2);

    	  ret = _asn1_extract_der_octet (node, der, *len);
    	  if (ret != ASN1_SUCCESS)
    	    return ret;

    	}
        }
      else
        {				/* NOT STRUCTURED */
          len2 = asn1_get_length_der (der, *len, &len3);
          if (len2 < 0)
    	return ASN1_DER_ERROR;

          counter = len3 + len2;
          if (node)
    	_asn1_set_value (node, der, counter);
        }

      *len = counter;
      return ASN1_SUCCESS;

    }
↓ | _asn1_convert_integer | 15 | 35 | 50 | element.c
    int
    _asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
    		       int value_out_size, int *len)
    {
      char negative;
      unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
      long valtmp;
      int k, k2;

      valtmp = _asn1_strtol (value, NULL, 10);

      for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
        {
          val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
        }

      if (val[0] & 0x80)
        negative = 1;
      else
        negative = 0;

      for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
        {
          if (negative && (val[k] != 0xFF))
    	break;
          else if (!negative && val[k])
    	break;
        }

      if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
        k--;

      *len = SIZEOF_UNSIGNED_LONG_INT - k;

      if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
        /* VALUE_OUT is too short to contain the value conversion */
        return ASN1_MEM_ERROR;

      for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
        value_out[k2 - k] = val[k2];

    #if 0
      printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
      for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
        printf (", vOut[%d]=%d", k, value_out[k]);
      printf ("\n");
    #endif

      return ASN1_SUCCESS;
    }
↓ | _asn1_objectid_der | 14 | 46 | 71 | coding.c
    static int
    _asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
    {
      int len_len, counter, k, first, max_len;
      char *temp, *n_end, *n_start;
      unsigned char bit7;
      unsigned long val, val1 = 0;
      int str_len = _asn1_strlen (str);

      max_len = *der_len;

      temp = malloc (str_len + 2);
      if (temp == NULL)
        return ASN1_MEM_ALLOC_ERROR;

      memcpy (temp, str, str_len);
      temp[str_len] = '.';
      temp[str_len + 1] = 0;

      counter = 0;
      n_start = temp;
      while ((n_end = strchr (n_start, '.')))
        {
          *n_end = 0;
          val = strtoul (n_start, NULL, 10);
          counter++;

          if (counter == 1)
    	val1 = val;
          else if (counter == 2)
    	{
    	  if (max_len > 0)
    	    der[0] = 40 * val1 + val;
    	  *der_len = 1;
    	}
          else
    	{
    	  first = 0;
    	  for (k = 4; k >= 0; k--)
    	    {
    	      bit7 = (val >> (k * 7)) & 0x7F;
    	      if (bit7 || first || !k)
    		{
    		  if (k)
    		    bit7 |= 0x80;
    		  if (max_len > (*der_len))
    		    der[*der_len] = bit7;
    		  (*der_len)++;
    		  first = 1;
    		}
    	    }

    	}
          n_start = n_end + 1;
        }

      asn1_length_der (*der_len, NULL, &len_len);
      if (max_len >= (*der_len + len_len))
        {
          memmove (der + len_len, der, *der_len);
          asn1_length_der (*der_len, der, &len_len);
        }
      *der_len += len_len;

      free (temp);

      if (max_len < (*der_len))
        return ASN1_MEM_ERROR;

      return ASN1_SUCCESS;
    }
↓ | _asn1_get_objectid_der | 14 | 38 | 61 | decoding.c
    static int
    _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
    			char *str, int str_size)
    {
      int len_len, len, k;
      int leading;
      char temp[20];
      unsigned long val, val1;

      *ret_len = 0;
      if (str && str_size > 0)
        str[0] = 0;			/* no oid */

      if (str == NULL || der_len <= 0)
        return ASN1_GENERIC_ERROR;

      len = asn1_get_length_der (der, der_len, &len_len);

      if (len < 0 || len > der_len || len_len > der_len)
        return ASN1_DER_ERROR;

      val1 = der[len_len] / 40;
      val = der[len_len] - val1 * 40;

      _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
      _asn1_str_cat (str, str_size, ".");
      _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));

      val = 0;
      leading = 1;
      for (k = 1; k < len; k++)
        {
          /* X.690 mandates that the leading byte must never be 0x80
           */
          if (leading != 0 && der[len_len + k] == 0x80)
    	return ASN1_DER_ERROR;
          leading = 0;

          /* check for wrap around */
          if (INT_LEFT_SHIFT_OVERFLOW (val, 7))
    	return ASN1_DER_ERROR;

          val = val << 7;
          val |= der[len_len + k] & 0x7F;

          if (!(der[len_len + k] & 0x80))
    	{
    	  _asn1_str_cat (str, str_size, ".");
    	  _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
    	  val = 0;
    	  leading = 1;
    	}
        }

      if (INT_ADD_OVERFLOW (len, len_len))
        return ASN1_DER_ERROR;

      *ret_len = len + len_len;

      return ASN1_SUCCESS;
    }
↓ | _asn1_type_set_config | 14 | 30 | 58 | parser_aux.c
    int
    _asn1_type_set_config (asn1_node node)
    {
      asn1_node p, p2;
      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) == ASN1_ETYPE_SET)
    	    {
    	      p2 = p->down;
    	      while (p2)
    		{
    		  if (type_field (p2->type) != ASN1_ETYPE_TAG)
    		    p2->type |= CONST_SET | CONST_NOT_USED;
    		  p2 = p2->right;
    		}
    	    }
    	  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;
    }
↓ | asn1_read_tag | 13 | 31 | 64 | element.c
    int
    asn1_read_tag (asn1_node root, const char *name, int *tagValue,
    	       int *classValue)
    {
      asn1_node node, p, pTag;

      node = asn1_find_node (root, name);
      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      p = node->down;

      /* pTag will points to the IMPLICIT TAG */
      pTag = NULL;
      if (node->type & CONST_TAG)
        {
          while (p)
    	{
    	  if (type_field (p->type) == ASN1_ETYPE_TAG)
    	    {
    	      if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
    		pTag = p;
    	      else if (p->type & CONST_EXPLICIT)
    		pTag = NULL;
    	    }
    	  p = p->right;
    	}
        }

      if (pTag)
        {
          *tagValue = _asn1_strtoul (pTag->value, NULL, 10);

          if (pTag->type & CONST_APPLICATION)
    	*classValue = ASN1_CLASS_APPLICATION;
          else if (pTag->type & CONST_UNIVERSAL)
    	*classValue = ASN1_CLASS_UNIVERSAL;
          else if (pTag->type & CONST_PRIVATE)
    	*classValue = ASN1_CLASS_PRIVATE;
          else
    	*classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
        }
      else
        {
          unsigned type = type_field (node->type);
          *classValue = ASN1_CLASS_UNIVERSAL;

          switch (type)
    	{
    	CASE_HANDLED_ETYPES:
    	  *tagValue = _asn1_tags[type].tag;
    	  break;
    	case ASN1_ETYPE_TAG:
    	case ASN1_ETYPE_CHOICE:
    	case ASN1_ETYPE_ANY:
    	  *tagValue = -1;
    	  break;
    	default:
    	  break;
    	}
        }

      return ASN1_SUCCESS;
    }
↓ | asn1_get_tag_der | 13 | 31 | 54 | decoding.c
    int
    asn1_get_tag_der (const unsigned char *der, int der_len,
    		  unsigned char *cls, int *len, unsigned long *tag)
    {
      unsigned int ris;
      int punt;

      if (der == NULL || der_len < 2 || len == NULL)
        return ASN1_DER_ERROR;

      *cls = der[0] & 0xE0;
      if ((der[0] & 0x1F) != 0x1F)
        {
          /* short form */
          *len = 1;
          ris = der[0] & 0x1F;
        }
      else
        {
          /* Long form */
          punt = 1;
          ris = 0;
          while (punt <= der_len && der[punt] & 128)
    	{

    	  if (INT_MULTIPLY_OVERFLOW (ris, 128))
    	    return ASN1_DER_ERROR;
    	  ris *= 128;

    	  if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
    	    return ASN1_DER_ERROR;
    	  ris += (der[punt] & 0x7F);
    	  punt++;
    	}

          if (punt >= der_len)
    	return ASN1_DER_ERROR;

          if (INT_MULTIPLY_OVERFLOW (ris, 128))
    	return ASN1_DER_ERROR;
          ris *= 128;

          if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
    	return ASN1_DER_ERROR;
          ris += (der[punt] & 0x7F);
          punt++;

          *len = punt;
        }

      if (tag)
        *tag = ris;
      return ASN1_SUCCESS;
    }
↓ | _asn1_delete_not_used | 13 | 30 | 58 | decoding.c
    static int
    _asn1_delete_not_used (asn1_node node)
    {
      asn1_node p, p2;

      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      p = node;
      while (p)
        {
          if (p->type & CONST_NOT_USED)
    	{
    	  p2 = NULL;
    	  if (p != node)
    	    {
    	      p2 = _asn1_find_left (p);
    	      if (!p2)
    		p2 = _asn1_find_up (p);
    	    }
    	  asn1_delete_structure (&p);
    	  p = p2;
    	}

          if (!p)
    	break;			/* reach node */

          if (p->down)
    	{
    	  p = p->down;
    	}
          else
    	{
    	  if (p == node)
    	    p = NULL;
    	  else if (p->right)
    	    p = p->right;
    	  else
    	    {
    	      while (1)
    		{
    		  p = _asn1_find_up (p);
    		  if (p == node)
    		    {
    		      p = NULL;
    		      break;
    		    }
    		  if (p->right)
    		    {
    		      p = p->right;
    		      break;
    		    }
    		}
    	    }
    	}
        }
      return ASN1_SUCCESS;
    }
↓ | _asn1_set_default_tag | 13 | 22 | 47 | parser_aux.c
    int
    _asn1_set_default_tag (asn1_node node)
    {
      asn1_node p;

      if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
        return ASN1_ELEMENT_NOT_FOUND;

      p = node;
      while (p)
        {
          if ((type_field (p->type) == ASN1_ETYPE_TAG) &&
    	  !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
    	{
    	  if (node->type & CONST_EXPLICIT)
    	    p->type |= CONST_EXPLICIT;
    	  else
    	    p->type |= CONST_IMPLICIT;
    	}

          if (p->down)
    	{
    	  p = p->down;
    	}
          else if (p->right)
    	p = p->right;
          else
    	{
    	  while (1)
    	    {
    	      p = _asn1_find_up (p);
    	      if (p == node)
    		{
    		  p = NULL;
    		  break;
    		}
    	      if (p->right)
    		{
    		  p = p->right;
    		  break;
    		}
    	    }
    	}
        }

      return ASN1_SUCCESS;
    }
↓ | _asn1_create_static_structure | 12 | 41 | 78 | structure.c
    int
    _asn1_create_static_structure (asn1_node pointer, char *output_file_name,
    			       char *vector_name)
    {
      FILE *file;
      asn1_node p;
      unsigned long t;

      file = fopen (output_file_name, "w");

      if (file == NULL)
        return ASN1_FILE_NOT_FOUND;

      fprintf (file, "#if HAVE_CONFIG_H\n");
      fprintf (file, "# include \"config.h\"\n");
      fprintf (file, "#endif\n\n");

      fprintf (file, "#include \n\n");

      fprintf (file, "const asn1_static_node %s[] = {\n", vector_name);

      p = pointer;

      while (p)
        {
          fprintf (file, "  { ");

          if (p->name[0] != 0)
    	fprintf (file, "\"%s\", ", p->name);
          else
    	fprintf (file, "NULL, ");

          t = p->type;
          if (p->down)
    	t |= CONST_DOWN;
          if (p->right)
    	t |= CONST_RIGHT;

          fprintf (file, "%lu, ", t);

          if (p->value)
    	fprintf (file, "\"%s\"},\n", p->value);
          else
    	fprintf (file, "NULL },\n");

          if (p->down)
    	{
    	  p = p->down;
    	}
          else if (p->right)
    	{
    	  p = p->right;
    	}
          else
    	{
    	  while (1)
    	    {
    	      p = _asn1_find_up (p);
    	      if (p == pointer)
    		{
    		  p = NULL;
    		  break;
    		}
    	      if (p->right)
    		{
    		  p = p->right;
    		  break;
    		}
    	    }
    	}
        }

      fprintf (file, "  { NULL, 0, NULL }\n};\n");

      fclose (file);

      return ASN1_SUCCESS;
    }
↓ | _asn1_change_integer_value | 12 | 28 | 57 | parser_aux.c
    int
    _asn1_change_integer_value (asn1_node node)
    {
      asn1_node p;
      unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
      unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
      int len;

      if (node == NULL)
        return ASN1_ELEMENT_NOT_FOUND;

      p = node;
      while (p)
        {
          if ((type_field (p->type) == ASN1_ETYPE_INTEGER)
    	  && (p->type & CONST_ASSIGN))
    	{
    	  if (p->value)
    	    {
    	      _asn1_convert_integer (p->value, val, sizeof (val), &len);
    	      asn1_octet_der (val, len, val2, &len);
    	      _asn1_set_value (p, val2, len);
    	    }
    	}

          if (p->down)
    	{
    	  p = p->down;
    	}
          else
    	{
    	  if (p == node)
    	    p = NULL;
    	  else if (p->right)
    	    p = p->right;
    	  else
    	    {
    	      while (1)
    		{
    		  p = _asn1_find_up (p);
    		  if (p == node)
    		    {
    		      p = NULL;
    		      break;
    		    }
    		  if (p->right)
    		    {
    		      p = p->right;
    		      break;
    		    }
    		}
    	    }
    	}
        }

      return ASN1_SUCCESS;
    }
↓ | asn1_get_length_der | 11 | 30 | 55 | decoding.c
    long
    asn1_get_length_der (const unsigned char *der, int der_len, int *len)
    {
      unsigned int ans;
      int k, punt, sum;

      *len = 0;
      if (der_len <= 0)
        return 0;

      if (!(der[0] & 128))
        {
          /* short form */
          *len = 1;
          ans = der[0];
        }
      else
        {
          /* Long form */
          k = der[0] & 0x7F;
          punt = 1;
          if (k)
    	{			/* definite length method */
    	  ans = 0;
    	  while (punt <= k && punt < der_len)
    	    {
    	      if (INT_MULTIPLY_OVERFLOW (ans, 256))
    		return -2;
    	      ans *= 256;

    	      if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt])))
    		return -2;
    	      ans += der[punt];
    	      punt++;
    	    }
    	}
          else
    	{			/* indefinite length method */
    	  *len = punt;
    	  return -1;
    	}

          *len = punt;
        }

      sum = ans;
      if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len)))
        return -2;
      sum += *len;

      if (sum > der_len)
        return -4;

      return ans;
    }
| _asn1_yyerror | 10 | 9 | 32 | ASN1.c
| _asn1_get_indefinite_length_string | 10 | 27 | 49 | decoding.c
| _asn1_complete_explicit_tag | 10 | 26 | 56 | coding.c
| _asn1_copy_structure3 | 9 | 33 | 56 | structure.c
| asn1_decode_simple_der | 9 | 27 | 44 | decoding.c
| asn1_find_structure_from_oid | 9 | 23 | 43 | structure.c
| asn1_parser2array | 8 | 47 | 107 | ASN1.c
| asn1_delete_structure | 8 | 25 | 50 | structure.c
| yytnamerr | 8 | 20 | 38 | ASN1.c
| asn1_encode_simple_der | 7 | 24 | 42 | coding.c
| _asn1_append_value | 7 | 22 | 39 | parser_aux.c
| _asn1_extract_der_octet | 7 | 20 | 44 | decoding.c
| _asn1_append_sequence_set | 7 | 20 | 33 | element.c
| _asn1_set_value | 7 | 17 | 31 | parser_aux.c
| asn1_length_der | 6 | 16 | 34 | coding.c
| asn1_parser2tree | 5 | 25 | 62 | ASN1.c
| asn1_copy_node | 5 | 21 | 40 | structure.c
| _asn1_tag_der | 5 | 16 | 32 | coding.c
| asn1_delete_element | 5 | 14 | 25 | structure.c
| asn1_number_of_elements | 5 | 13 | 25 | structure.c
| _asn1_set_value_m | 5 | 12 | 22 | parser_aux.c
| _asn1_get_time_der | 5 | 10 | 17 | decoding.c
| _asn1_find_up | 4 | 7 | 15 | parser_aux.c
| _asn1_remove_node | 4 | 5 | 10 | parser_aux.c
| _asn1_find_left | 4 | 3 | 8 | structure.c
| _asn1_ltostr | 4 | 22 | 32 | parser_aux.c
| _asn1_hierarchical_name | 4 | 12 | 25 | element.c
| asn1_get_bit_der | 4 | 12 | 25 | decoding.c
| _asn1_time_der | 4 | 11 | 20 | coding.c
| asn1_get_octet_der | 4 | 11 | 26 | decoding.c
| yy_symbol_value_print | 4 | 6 | 24 | ASN1.c
| _asn1_create_errorDescription | 3 | 12 | 31 | ASN1.c
| _asn1_cpy_name | 3 | 9 | 18 | parser_aux.c
| asn1_get_length_ber | 3 | 9 | 17 | decoding.c
| asn1_strerror | 3 | 7 | 11 | errors.c
| _asn1_get_last_right | 3 | 7 | 12 | parser_aux.c
| _asn1_str_cat | 3 | 7 | 19 | gstr.c
| _asn1_set_down | 3 | 6 | 10 | parser_aux.h
| _asn1_set_right | 3 | 6 | 10 | parser_aux.c
| asn1_octet_der | 3 | 6 | 13 | coding.c
| asn1_check_version | 3 | 3 | 8 | version.c
| _asn1_add_static_node | 3 | 14 | 25 | parser_aux.c
| asn1_bit_der | 3 | 13 | 21 | coding.c
| _asn1_str_cpy | 3 | 10 | 23 | gstr.c
| _asn1_set_name | 3 | 10 | 20 | parser_aux.c
| _asn1_set_value_lv | 3 | 10 | 17 | parser_aux.c
| convert_old_type | 3 | 10 | 20 | int.h
| yydestruct | 3 | 5 | 23 | ASN1.c
| yy_stack_print | 2 | 7 | 17 | ASN1.c
| _asn1_delete_list_and_nodes | 2 | 6 | 13 | parser_aux.c
| _asn1_add_single_node | 2 | 6 | 13 | structure.c
| yystrlen | 2 | 6 | 13 | ASN1.c
| _asn1_delete_list | 2 | 5 | 12 | parser_aux.c
| _asn1_error_description_value_not_found | 2 | 5 | 14 | coding.c
| yystpcpy | 2 | 5 | 17 | ASN1.c
| yy_symbol_print | 2 | 5 | 18 | ASN1.c
| _asn1_mod_type | 2 | 4 | 8 | parser_aux.h
| _asn1_get_right | 2 | 3 | 7 | parser_aux.h
| asn1_perror | 2 | 3 | 6 | errors.c
| _asn1_get_name | 2 | 3 | 7 | parser_aux.h
| _asn1_get_down | 2 | 3 | 7 | parser_aux.h
| asn1_create_element | 2 | 10 | 21 | structure.c
| yy_reduce_print | 2 | 10 | 24 | ASN1.c
| asn1_read_node_value | 1 | 5 | 10 | element.c
| _asn1_copy_structure2 | 1 | 3 | 10 | structure.c
| _asn1_error_description_tag_error | 1 | 3 | 10 | decoding.c
| asn1_read_value | 1 | 1 | 5 | element.c
| YYID | 1 | 1 | 10 | ASN1.c
| type_field | 1 | 1 | 5 | int.h

Copyright (c) 2007, 2008 Free Software Foundation, Inc.